package qa.gov.moi.erp.core.business.budget;

import java.math.BigDecimal;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import qa.gov.moi.erp.core.dao.BudgetAllocationDao;
import qa.gov.moi.erp.core.dao.ProgramDao;
import qa.gov.moi.erp.core.dao.ProgramDistributionDao;
import qa.gov.moi.erp.core.dao.ProgramYearsDao;
import qa.gov.moi.erp.core.framework.utility.ERPCoreUtility;
import qa.gov.moi.erp.util.dto.MessageDTO;
import qa.gov.moi.erp.util.dto.budget.BudgetDetailsDTO;
import qa.gov.moi.erp.util.dto.budget.BudgetTransactionDTO;
import qa.gov.moi.erp.util.dto.budget.COADepartmentDTO;
import qa.gov.moi.erp.util.dto.budget.CoaMoiDTO;
import qa.gov.moi.erp.util.dto.program.ProgramDistributionDTO;
import qa.gov.moi.erp.util.exceptions.ERPException;
import qa.gov.moi.erp.util.helpers.ERPTransactionsTypes;
import qa.gov.moi.erp.util.helpers.ERPUtility;

public class BudgetAllocationManager
{

    private final Logger log = LoggerFactory.getLogger(BudgetAllocationManager.class);

    public List<MessageDTO> createBOYReceiveApprovedAmount(Connection connection, BudgetTransactionDTO budgetTransactionDTO) throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO,Set<String> reasonCode ) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.BOY_RECEIVE_APPROVED);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }

            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public List<MessageDTO> execBOYReceiveApprovedAmount(Connection connection, String transactionSetId) throws ERPException
    {

        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        CoaMoiDTO coaMoi = new CoaMoiDTO();
        CoaMoiDTO coaMoiDTO = new CoaMoiDTO();

        String fiscalYear = null;
        String minCode = null;
        String accountNum = null;
        String accountSubNum = null;
        String transactionType = null;
        String transactionStatus = null;
        if (log.isInfoEnabled())
        {
            log.info(methodName + "( called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();
            Set<BudgetTransactionDTO> budgetTransactionCollection = new HashSet<BudgetTransactionDTO>();
            budgetTransactionCollection = budgetAllocationDao.readBudgetTransaction(connection,BudgetTransactionDTO.class.newInstance(),transactionSetId,true);

            for (BudgetTransactionDTO budgetTransactionDTO : budgetTransactionCollection)
            {
                transactionType = budgetTransactionDTO.getAC8_TRANSACTION_TYPE();
                transactionStatus = budgetTransactionDTO.getAC8_TRANSACTION_STATUS();
                fiscalYear = budgetTransactionDTO.getAC8_FISCAL_YEAR();
                minCode = budgetTransactionDTO.getAC8_ACCOUNT_MINISTRY_NUMBER();
                accountNum = budgetTransactionDTO.getAC8_ACCOUNT_NUMBER();
                accountSubNum = budgetTransactionDTO.getAC8_ACCOUNT_SUB_NUMBER();

                coaMoi.setAC0_FISCAL_YEAR(fiscalYear);
                coaMoi.setAC0_ACCOUNT_MINISTRY_NUMBER(minCode);
                coaMoi.setAC0_ACCOUNT_NUMBER(accountNum);
                coaMoi.setAC0_ACCOUNT_SUB_NUMBER(accountSubNum);

                coaMoiDTO = budgetAllocationDao.readBudgetAllocation(connection,coaMoi,true);

                if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
                {
                    if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.BOY_RECEIVE_APPROVED))
                    {
                        if (coaMoiDTO != null)
                        {
                            coaMoiDTO.setAC0_APPROVED(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());
                            budgetAllocationDao.updateCoaMoi(connection,budgetTransactionDTO,coaMoiDTO,transactionType); // Update COA_MOI

                            budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO);// Update VAC8_BUDGET_TRANSACTION set status = 'POSTED'
                        }
                    }
                }
            }

            if (messages.isEmpty())
            {
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null);
            }
            return messages;
        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }

    }

    public List<MessageDTO> createBOYSetEstimatedAmount(Connection connection, BudgetTransactionDTO budgetTransactionDTO) throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.BOY_SET_ESTIMATED_AMOUNT);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }
            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public List<MessageDTO> execBOYSetEstimatedAmount(Connection connection, String transactionSetId) throws ERPException
    {

        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        CoaMoiDTO coaMoi = new CoaMoiDTO();
        CoaMoiDTO coaMoiDTO = new CoaMoiDTO();
        COADepartmentDTO coaDepartmentDTO = new COADepartmentDTO();
        // We are just creating it as we need to pass it as an argument to update department details
        BudgetDetailsDTO budgetDetailsDTO = null;

        String fiscalYear = null;
        String minCode = null;
        String accountNum = null;
        String accountSubNum = null;
        String transactionType = null;
        String transactionStatus = null;
        if (log.isInfoEnabled())
        {
            log.info(methodName + "( called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();
            Set<BudgetTransactionDTO> budgetTransactionCollection = new HashSet<BudgetTransactionDTO>();
            budgetTransactionCollection = budgetAllocationDao.readBudgetTransaction(connection,BudgetTransactionDTO.class.newInstance(),transactionSetId,true);

            for (BudgetTransactionDTO budgetTransactionDTO : budgetTransactionCollection)
            {
                transactionType = budgetTransactionDTO.getAC8_TRANSACTION_TYPE();
                transactionStatus = budgetTransactionDTO.getAC8_TRANSACTION_STATUS();
                fiscalYear = budgetTransactionDTO.getAC8_FISCAL_YEAR();
                minCode = budgetTransactionDTO.getAC8_ACCOUNT_MINISTRY_NUMBER();
                accountNum = budgetTransactionDTO.getAC8_ACCOUNT_NUMBER();
                accountSubNum = budgetTransactionDTO.getAC8_ACCOUNT_SUB_NUMBER();

                coaMoi.setAC0_FISCAL_YEAR(fiscalYear);
                coaMoi.setAC0_ACCOUNT_MINISTRY_NUMBER(minCode);
                coaMoi.setAC0_ACCOUNT_NUMBER(accountNum);
                coaMoi.setAC0_ACCOUNT_SUB_NUMBER(accountSubNum);

                coaMoiDTO = budgetAllocationDao.readBudgetAllocation(connection,coaMoi,true);

                coaDepartmentDTO = budgetAllocationDao.readDepartmentDetails(connection,budgetTransactionDTO);

                if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
                {
                    if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.BOY_SET_ESTIMATED_AMOUNT))
                    {
                        if (coaMoiDTO != null && coaDepartmentDTO != null)
                        {
                            coaDepartmentDTO.setAC2_ESTIMATED(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());
                            budgetAllocationDao.updateDepartmentDetails(connection,budgetTransactionDTO,budgetDetailsDTO,coaDepartmentDTO,transactionType);

                            coaMoiDTO.setAC0_ESTIMATED(coaMoiDTO.getAC0_ESTIMATED().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            budgetAllocationDao.updateCoaMoi(connection,budgetTransactionDTO,coaMoiDTO,transactionType); // Update COA_MOI
                            budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO);// Update VAC8_BUDGET_TRANSACTION set status = 'POSTED'
                        }
                    }
                }
            }

            if (messages.isEmpty())
            {
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null);
            }
            return messages;
        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }

    }

    public List<MessageDTO> createBOYDistributeNonDistributed(Connection connection, BudgetTransactionDTO budgetTransactionDTO) throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.BOY_DISTRIBUTE_NON_DISTRIBUTED);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }

            return messages;
        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public List<MessageDTO> execBOYDistributeNonDistributed(Connection connection, String transactionSetId) throws ERPException
    {

        log.info("nonDistributedApproved called.");

        CoaMoiDTO coaMoi = new CoaMoiDTO();
        CoaMoiDTO coaMoiDTO = new CoaMoiDTO();

        String fiscalYear = null;
        String minCode = null;
        String accountNum = null;
        String accountSubNum = null;
        String transactionType = null;
        String transactionStatus = null;
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "called.");
        }

        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();
            Set<BudgetTransactionDTO> budgetTransactionCollection = new HashSet<BudgetTransactionDTO>();
            budgetTransactionCollection = budgetAllocationDao.readBudgetTransaction(connection,BudgetTransactionDTO.class.newInstance(),transactionSetId,true);

            for (BudgetTransactionDTO budgetTransactionDTO : budgetTransactionCollection)
            {
                transactionType = budgetTransactionDTO.getAC8_TRANSACTION_TYPE();
                transactionStatus = budgetTransactionDTO.getAC8_TRANSACTION_STATUS();
                fiscalYear = budgetTransactionDTO.getAC8_FISCAL_YEAR();
                minCode = budgetTransactionDTO.getAC8_ACCOUNT_MINISTRY_NUMBER();
                accountNum = budgetTransactionDTO.getAC8_ACCOUNT_NUMBER();
                accountSubNum = budgetTransactionDTO.getAC8_ACCOUNT_SUB_NUMBER();

                coaMoi.setAC0_FISCAL_YEAR(fiscalYear);
                coaMoi.setAC0_ACCOUNT_MINISTRY_NUMBER(minCode);
                coaMoi.setAC0_ACCOUNT_NUMBER(accountNum);
                coaMoi.setAC0_ACCOUNT_SUB_NUMBER(accountSubNum);

                coaMoiDTO = budgetAllocationDao.readBudgetAllocation(connection,coaMoi,true);

                if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
                {
                    if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.BOY_DISTRIBUTE_NON_DISTRIBUTED))
                    {
                        if (coaMoiDTO != null)
                        {
                            coaMoiDTO.setAC0_NON_DISTRIBUTED(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());
                            budgetAllocationDao.updateCoaMoi(connection,budgetTransactionDTO,coaMoiDTO,transactionType); // Update COA_MOI

                            budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO); // Update VAC8_BUDGET_TRANSACTION set status =
                        }
                    }
                }

            }

            if (messages.isEmpty())
            {
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null);
            }
            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
    }

    public List<MessageDTO> createBOYDistributeNonProgram(Connection connection, BudgetTransactionDTO budgetTransactionDTO) throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.BOY_DISTRIBUTE_NON_PROGRAM);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }

            return messages;
        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public List<MessageDTO> execBOYDistributeNonProgram(Connection connection, String transactionSetId) throws ERPException
    {

        CoaMoiDTO coaMoi = new CoaMoiDTO();
        CoaMoiDTO coaMoiDTO = new CoaMoiDTO();
        COADepartmentDTO coaDepartmentDTO = new COADepartmentDTO();
        ProgramDistributionDTO programDistributionDTO = new ProgramDistributionDTO();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        BigDecimal extraApprovedAmount = new BigDecimal(0);
        BigDecimal departmentFreeBalance = new BigDecimal(0);
        BigDecimal coaMoifreeBalance = new BigDecimal(0);
        BigDecimal totalNonProgramApproved = new BigDecimal(0);
        BigDecimal coaNonProgramApproved = new BigDecimal(0);
        String fiscalYear = null;
        String minCode = null;
        String accountNum = null;
        String accountSubNum = null;
        String transactionType = null;
        String transactionStatus = null;
        String programRefNumber = null;
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        if (log.isInfoEnabled())
        {
            log.info(methodName + "( called.");
        }
        int count = 0;

        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();
            BudgetDetailsDTO budgetDetailsDTO = new BudgetDetailsDTO();

            Set<BudgetTransactionDTO> budgetTransactionCollection = new HashSet<BudgetTransactionDTO>();

            budgetTransactionCollection = budgetAllocationDao.readBudgetTransaction(connection,BudgetTransactionDTO.class.newInstance(),transactionSetId,true);

            for (BudgetTransactionDTO budgetTransactionDTO : budgetTransactionCollection)
            {

                transactionType = budgetTransactionDTO.getAC8_TRANSACTION_TYPE();
                transactionStatus = budgetTransactionDTO.getAC8_TRANSACTION_STATUS();
                fiscalYear = budgetTransactionDTO.getAC8_FISCAL_YEAR();
                minCode = budgetTransactionDTO.getAC8_ACCOUNT_MINISTRY_NUMBER();
                accountNum = budgetTransactionDTO.getAC8_ACCOUNT_NUMBER();
                accountSubNum = budgetTransactionDTO.getAC8_ACCOUNT_SUB_NUMBER();
                extraApprovedAmount = budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT();
                programRefNumber = budgetTransactionDTO.getAC8_PROGRAM_REF_NUMBER().trim();

                coaMoi.setAC0_FISCAL_YEAR(fiscalYear);
                coaMoi.setAC0_ACCOUNT_MINISTRY_NUMBER(minCode);
                coaMoi.setAC0_ACCOUNT_NUMBER(accountNum);
                coaMoi.setAC0_ACCOUNT_SUB_NUMBER(accountSubNum);
                coaMoi.setAC0_EXTRA_APPROVED(extraApprovedAmount);

                coaMoiDTO = budgetAllocationDao.readBudgetAllocation(connection,coaMoi,false);

                coaDepartmentDTO = budgetAllocationDao.readDepartmentDetails(connection,budgetTransactionDTO);

                if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
                {
                    if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.BOY_DISTRIBUTE_NON_PROGRAM))
                    {
                        if (coaMoiDTO != null && coaDepartmentDTO != null && programRefNumber.equals("0"))
                        {
                            Set<COADepartmentDTO> set = budgetAllocationDao.readAllDepartmentDetails(connection,coaMoi);

                            for (Iterator<COADepartmentDTO> it = set.iterator(); it.hasNext();)
                            {
                                COADepartmentDTO departmentDTO = (COADepartmentDTO)it.next();
                                totalNonProgramApproved = totalNonProgramApproved.add(departmentDTO.getAC2_NON_PROGRAM_APPROVED());

                            }
                            coaNonProgramApproved = coaMoiDTO.getAC0_NON_PROGRAM_APPROVED().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());
                            totalNonProgramApproved = totalNonProgramApproved.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                            if (coaNonProgramApproved.compareTo(totalNonProgramApproved) >= 0)
                            {
                                budgetDetailsDTO = budgetAllocationDao.distributeToBudgetDetails(budgetTransactionDTO,programDistributionDTO);
                                count = budgetAllocationDao.insertBudgetDetails(connection,budgetTransactionDTO,budgetDetailsDTO,coaDepartmentDTO,
                                        transactionType);

                                if (count > 0)
                                {
                                    departmentFreeBalance = coaDepartmentDTO.getAC2_APPROVED().add(coaDepartmentDTO.getAC2_EXTRA_APPROVED())
                                            .add(coaDepartmentDTO.getAC2_TRANSFERED_TO()).add(coaDepartmentDTO.getAC2_PV_CREDIT_TOTAL())
                                            .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_COMMITMENT())
                                            .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaDepartmentDTO.getAC2_PV_DEBIT_TOTAL())
                                            .subtract(coaDepartmentDTO.getAC2_TRANSFERED_FROM());

                                    departmentFreeBalance = departmentFreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                                    coaDepartmentDTO.setAC2_NON_PROGRAM_APPROVED(coaDepartmentDTO.getAC2_NON_PROGRAM_APPROVED().add(
                                            budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                    coaDepartmentDTO.setAC2_APPROVED(coaDepartmentDTO.getAC2_APPROVED().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                    coaDepartmentDTO.setAC2_FREE_BALANCE(departmentFreeBalance);

                                    budgetAllocationDao.updateDepartmentDetails(connection,budgetTransactionDTO,budgetDetailsDTO,coaDepartmentDTO,
                                            transactionType);
                                }
                                coaMoifreeBalance = coaMoiDTO.getAC0_APPROVED().add(coaMoiDTO.getAC0_EXTRA_APPROVED()).add(coaMoiDTO.getAC0_TRANSFERED_TO())
                                        .add(coaMoiDTO.getAC0_PV_CREDIT_TOTAL()).subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_COMMITMENT())
                                        .subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaMoiDTO.getAC0_PV_DEBIT_TOTAL())
                                        .subtract(coaMoiDTO.getAC0_TRANSFERED_FROM());

                                coaMoifreeBalance = coaMoifreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                                coaMoiDTO.setAC0_NON_PROGRAM_APPROVED(coaMoiDTO.getAC0_NON_PROGRAM_APPROVED().add(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                coaMoiDTO.setAC0_FREE_BALANCE(coaMoifreeBalance);

                                budgetAllocationDao.updateCoaMoi(connection,budgetTransactionDTO,coaMoiDTO,transactionType); // Update COA_MOI

                                budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO); // Update VAC8_BUDGET_TRANSACTION
                            }
                            else
                            {
                                log.info("NonProgram amounts mismatch at DEPT and COA level");
                                String[] arguments =
                                { budgetTransactionDTO.getAC8_TRANSACTION_TYPE(), "null", "null" };
                                ERPCoreUtility.addResultCode(ERPTransactionsTypes.BUDGET_EXECUTION_CODE.AMOUNT_MISMATCH,messages,arguments,true);
                                return messages;
                            }
                        }
                    }
                }
            }

            if (messages.isEmpty())
            {
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null);
            }
            return messages;
        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
    }

    public List<MessageDTO> createBOYDistributeProgram(Connection connection, BudgetTransactionDTO budgetTransactionDTO) throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.BOY_DISTRIBUTE_PROGRAM);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }
            return messages;
        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public List<MessageDTO> execBOYDistributeProgram(Connection connection, String transactionSetId) throws ERPException
    {

        CoaMoiDTO coaMoi = new CoaMoiDTO();
        CoaMoiDTO coaMoiDTO = new CoaMoiDTO();
        COADepartmentDTO coaDepartmentDTO = new COADepartmentDTO();
        ProgramDistributionDTO programDistributionDTO = new ProgramDistributionDTO();
        ProgramDistributionDao programDistributionDao = new ProgramDistributionDao();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        BigDecimal extraApprovedAmount = new BigDecimal(0);
        BigDecimal departmentFreeBalance = new BigDecimal(0);
        BigDecimal coaProgramApproved = new BigDecimal(0);
        BigDecimal totalProgramApproved = new BigDecimal(0);
        BigDecimal coaMoifreeBalance = new BigDecimal(0);
        String fiscalYear = null;
        String minCode = null;
        String accountNum = null;
        String accountSubNum = null;
        String transactionType = null;
        String transactionStatus = null;
        String departmentId = null;
        String programRefNumber = null;
        BigDecimal transactionAmount = new BigDecimal(0);
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "( called.");
        }
        int count = 0;

        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();
            Set<BudgetTransactionDTO> budgetTransactionCollection = new HashSet<BudgetTransactionDTO>();
            BudgetDetailsDTO budgetDetailsDTO = new BudgetDetailsDTO();
            budgetTransactionCollection = budgetAllocationDao.readBudgetTransaction(connection,BudgetTransactionDTO.class.newInstance(),transactionSetId,false);

            for (BudgetTransactionDTO budgetTransactionDTO : budgetTransactionCollection)
            {
                transactionType = budgetTransactionDTO.getAC8_TRANSACTION_TYPE();
                transactionStatus = budgetTransactionDTO.getAC8_TRANSACTION_STATUS();
                fiscalYear = budgetTransactionDTO.getAC8_FISCAL_YEAR();
                minCode = budgetTransactionDTO.getAC8_ACCOUNT_MINISTRY_NUMBER();
                accountNum = budgetTransactionDTO.getAC8_ACCOUNT_NUMBER();
                accountSubNum = budgetTransactionDTO.getAC8_ACCOUNT_SUB_NUMBER();
                departmentId = budgetTransactionDTO.getAC8_DEPARTMENT();
                extraApprovedAmount = budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT();
                programRefNumber = budgetTransactionDTO.getAC8_PROGRAM_REF_NUMBER().trim();
                transactionAmount = budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT();

                programDistributionDTO = programDistributionDao.readProgramDistribution(connection,minCode,accountNum,accountSubNum,fiscalYear,
                        programRefNumber,departmentId,false);
                coaMoi.setAC0_FISCAL_YEAR(fiscalYear);
                coaMoi.setAC0_ACCOUNT_MINISTRY_NUMBER(minCode);
                coaMoi.setAC0_ACCOUNT_NUMBER(accountNum);
                coaMoi.setAC0_ACCOUNT_SUB_NUMBER(accountSubNum);
                coaMoi.setAC0_EXTRA_APPROVED(extraApprovedAmount);

                coaMoiDTO = budgetAllocationDao.readBudgetAllocation(connection,coaMoi,false);

                coaDepartmentDTO = budgetAllocationDao.readDepartmentDetails(connection,budgetTransactionDTO);

                if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
                {
                    if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.BOY_DISTRIBUTE_PROGRAM))
                    {
                        if (coaMoiDTO != null && coaDepartmentDTO != null && programDistributionDTO != null)
                        {
                            Set<COADepartmentDTO> set = budgetAllocationDao.readAllDepartmentDetails(connection,coaMoi);

                            for (Iterator<COADepartmentDTO> it = set.iterator(); it.hasNext();)
                            {
                                COADepartmentDTO departmentDTO = (COADepartmentDTO)it.next();
                                totalProgramApproved = totalProgramApproved.add(departmentDTO.getAC2_PROGRAM_APPROVED());

                            }
                            coaProgramApproved = coaMoiDTO.getAC0_PROGRAM_APPROVED().add(transactionAmount);
                            totalProgramApproved = totalProgramApproved.add(transactionAmount);

                            if (coaProgramApproved.compareTo(totalProgramApproved) >= 0)
                            {
                                budgetDetailsDTO = budgetAllocationDao.distributeToBudgetDetails(budgetTransactionDTO,programDistributionDTO);

                                count = budgetAllocationDao.insertBudgetDetails(connection,budgetTransactionDTO,budgetDetailsDTO,coaDepartmentDTO,
                                        transactionType); // Insert Budget details

                                if (count > 0)
                                {
                                    departmentFreeBalance = coaDepartmentDTO.getAC2_APPROVED().add(coaDepartmentDTO.getAC2_EXTRA_APPROVED())
                                            .add(coaDepartmentDTO.getAC2_TRANSFERED_TO()).add(coaDepartmentDTO.getAC2_PV_CREDIT_TOTAL())
                                            .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_COMMITMENT())
                                            .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaDepartmentDTO.getAC2_PV_DEBIT_TOTAL())
                                            .subtract(coaDepartmentDTO.getAC2_TRANSFERED_FROM());

                                    departmentFreeBalance = departmentFreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                                    coaDepartmentDTO.setAC2_PROGRAM_APPROVED(coaDepartmentDTO.getAC2_PROGRAM_APPROVED().add(
                                            budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                    coaDepartmentDTO.setAC2_APPROVED(coaDepartmentDTO.getAC2_APPROVED().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                    coaDepartmentDTO.setAC2_FREE_BALANCE(departmentFreeBalance);

                                    budgetAllocationDao.updateDepartmentDetails(connection,budgetTransactionDTO,budgetDetailsDTO,coaDepartmentDTO,
                                            transactionType);
                                }

                                coaMoifreeBalance = coaMoiDTO.getAC0_APPROVED().add(coaMoiDTO.getAC0_EXTRA_APPROVED()).add(coaMoiDTO.getAC0_TRANSFERED_TO())
                                        .add(coaMoiDTO.getAC0_PV_CREDIT_TOTAL()).subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_COMMITMENT())
                                        .subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaMoiDTO.getAC0_PV_DEBIT_TOTAL())
                                        .subtract(coaMoiDTO.getAC0_TRANSFERED_FROM());

                                coaMoifreeBalance = coaMoifreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                                coaMoiDTO.setAC0_PROGRAM_APPROVED(coaMoiDTO.getAC0_PROGRAM_APPROVED().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                coaMoiDTO.setAC0_FREE_BALANCE(coaMoifreeBalance);

                                budgetAllocationDao.updateCoaMoi(connection,budgetTransactionDTO,coaMoiDTO,transactionType); // Update COA_MOI

                                budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO); // Update VAC8_BUDGET_TRANSACTION
                            }
                            else
                            {
                                log.info("Program amounts mismatch at DEPT and COA level");
                                String[] arguments =
                                { budgetTransactionDTO.getAC8_TRANSACTION_TYPE(), "null", "null" };
                                ERPCoreUtility.addResultCode(ERPTransactionsTypes.BUDGET_EXECUTION_CODE.AMOUNT_MISMATCH,messages,arguments,true);
                                return messages;

                            }
                        }
                    }
                }
            }

            if (messages.isEmpty())
            {
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null);
            }
            return messages;
        }

        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
    }

    // CREATE EXTRA AMOUNT FOR PROG CURRENT YR TRANSACTION
    /**
     * 
     * This process will be called whenever extra amount (apart from amount Approved in BOY) which is taken from Future year is given to the current year
     * Program fund of a Department of Budget Clause. This process will create a record in the TAC8_BUDGET_TRANSACTION table using the input which is passed to
     * this process.
     */

    public List<MessageDTO> createExtraAmountForProgCurrentYR(Connection connection, BudgetTransactionDTO budgetTransactionDTO) throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO,Set reasonCode ) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                String transactionId = UUID.randomUUID().toString().replaceAll("-","");

                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.PROGRAM_CURRENT_EXTRA_APPROVED);
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }
            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public List<MessageDTO> execExtraAmountForProgCurrentYR(Connection connection, String transactionSetId) throws ERPException
    {

        CoaMoiDTO coaMoi = new CoaMoiDTO();
        CoaMoiDTO coaMoiDTO = new CoaMoiDTO();
        COADepartmentDTO coaDepartmentDTO = new COADepartmentDTO();
        ProgramDistributionDTO programDistributionDTO = new ProgramDistributionDTO();
        ProgramDistributionDao programDistributionDao = new ProgramDistributionDao();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();
        ProgramYearsDao programYearsDao = new ProgramYearsDao();

        BigDecimal extraApprovedAmount = new BigDecimal(0);
        BigDecimal budgetDetailsFreeBalance = new BigDecimal(0);
        BigDecimal departmentFreeBalance = new BigDecimal(0);
        BigDecimal coaMoifreeBalance = new BigDecimal(0);
        String fiscalYear = null;
        String minCode = null;
        String accountNum = null;
        String accountSubNum = null;
        String transactionType = null;
        String transactionStatus = null;
        String departmentId = null;
        String programRefNumber = null;
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        if (log.isInfoEnabled())
        {
            log.info(methodName + "( called.");
        }
        int count = 0;

        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            Set<BudgetTransactionDTO> budgetTransactionCollection = new HashSet<BudgetTransactionDTO>();
            BudgetDetailsDTO budgetDetailsDTO = new BudgetDetailsDTO();

            budgetTransactionCollection = budgetAllocationDao.readBudgetTransaction(connection,BudgetTransactionDTO.class.newInstance(),transactionSetId,true);

            for (BudgetTransactionDTO budgetTransactionDTO : budgetTransactionCollection)
            {

                transactionType = budgetTransactionDTO.getAC8_TRANSACTION_TYPE();
                transactionStatus = budgetTransactionDTO.getAC8_TRANSACTION_STATUS();
                fiscalYear = budgetTransactionDTO.getAC8_FISCAL_YEAR();
                minCode = budgetTransactionDTO.getAC8_ACCOUNT_MINISTRY_NUMBER();
                accountNum = budgetTransactionDTO.getAC8_ACCOUNT_NUMBER();
                accountSubNum = budgetTransactionDTO.getAC8_ACCOUNT_SUB_NUMBER();
                departmentId = budgetTransactionDTO.getAC8_DEPARTMENT();
                extraApprovedAmount = budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT();
                programRefNumber = budgetTransactionDTO.getAC8_PROGRAM_REF_NUMBER().trim();

                coaMoi.setAC0_FISCAL_YEAR(fiscalYear);
                coaMoi.setAC0_ACCOUNT_MINISTRY_NUMBER(minCode);
                coaMoi.setAC0_ACCOUNT_NUMBER(accountNum);
                coaMoi.setAC0_ACCOUNT_SUB_NUMBER(accountSubNum);
                coaMoi.setAC0_EXTRA_APPROVED(extraApprovedAmount);

                coaMoiDTO = budgetAllocationDao.readBudgetAllocation(connection,coaMoi,false);

                coaDepartmentDTO = budgetAllocationDao.readDepartmentDetails(connection,budgetTransactionDTO);

                programDistributionDTO = programDistributionDao.readProgramDistribution(connection,minCode,accountNum,accountSubNum,fiscalYear,
                        programRefNumber,departmentId,false);

                budgetDetailsDTO = budgetAllocationDao.readBudgetDetails(connection,fiscalYear,minCode,accountNum,accountSubNum,departmentId,programRefNumber,
                        true);

                if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
                {
                    if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.PROGRAM_CURRENT_EXTRA_APPROVED))
                    {
                        if (coaMoiDTO != null && coaDepartmentDTO != null && programDistributionDTO != null)
                        {
                            budgetDetailsFreeBalance = budgetDetailsDTO.getAC3_AMOUNT_APPROVED().add(budgetDetailsDTO.getAC3_PV_CREDIT_TOTAL())
                                    .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_COMMITMENT())
                                    .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_OBLIGATION()).subtract(budgetDetailsDTO.getAC3_PV_DEBIT_TOTAL());

                            budgetDetailsFreeBalance = budgetDetailsFreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                            budgetDetailsDTO.setAC3_AMOUNT_APPROVED(budgetDetailsDTO.getAC3_AMOUNT_APPROVED().add(
                                    budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            budgetDetailsDTO.setAC3_FREE_BALANCE(budgetDetailsFreeBalance);

                            count = budgetAllocationDao.updateBudgetDetails(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType); // Update Budget

                            if (count > 0)
                            {
                                departmentFreeBalance = coaDepartmentDTO.getAC2_APPROVED().add(coaDepartmentDTO.getAC2_EXTRA_APPROVED())
                                        .add(coaDepartmentDTO.getAC2_TRANSFERED_TO()).add(coaDepartmentDTO.getAC2_PV_CREDIT_TOTAL())
                                        .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_COMMITMENT())
                                        .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaDepartmentDTO.getAC2_PV_DEBIT_TOTAL())
                                        .subtract(coaDepartmentDTO.getAC2_TRANSFERED_FROM());

                                departmentFreeBalance = departmentFreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                                coaDepartmentDTO.setAC2_EXTRA_APPROVED(coaDepartmentDTO.getAC2_EXTRA_APPROVED().add(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                coaDepartmentDTO.setAC2_PROGRAM_APPROVED(coaDepartmentDTO.getAC2_PROGRAM_APPROVED().add(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                coaDepartmentDTO.setAC2_FREE_BALANCE(departmentFreeBalance);

                                budgetAllocationDao.updateDepartmentDetails(connection,budgetTransactionDTO,budgetDetailsDTO,coaDepartmentDTO,transactionType);
                            }
                            coaMoifreeBalance = coaMoiDTO.getAC0_APPROVED().add(coaMoiDTO.getAC0_EXTRA_APPROVED()).add(coaMoiDTO.getAC0_TRANSFERED_TO())
                                    .add(coaMoiDTO.getAC0_PV_CREDIT_TOTAL()).subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_COMMITMENT())
                                    .subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaMoiDTO.getAC0_PV_DEBIT_TOTAL())
                                    .subtract(coaMoiDTO.getAC0_TRANSFERED_FROM());

                            coaMoifreeBalance = coaMoifreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                            coaMoiDTO.setAC0_EXTRA_APPROVED(coaMoiDTO.getAC0_EXTRA_APPROVED().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            coaMoiDTO.setAC0_PROGRAM_APPROVED(coaMoiDTO.getAC0_PROGRAM_APPROVED().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            coaMoiDTO.setAC0_FREE_BALANCE(coaMoifreeBalance);

                            budgetAllocationDao.updateCoaMoi(connection,budgetTransactionDTO,coaMoiDTO,transactionType); // Update COA_MOI

                            budgetTransactionDTO.setAC8_ACCOUNT_NUMBER(accountNum);
                            budgetTransactionDTO.setAC8_ACCOUNT_SUB_NUMBER(accountSubNum);

                            // Update VPJ2_PROGRAM_DISTRIBUTION
                            programDistributionDao.updateProgramDistribution(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);

                            // Update VPJ1_PROGRAM_YEARS
                            programYearsDao.updateProgramYears(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);

                            budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO); // Update VAC8_BUDGET_TRANSACTION
                        }
                        else
                        {
                            log.info("Record not found in BUDGET_DETAILS during execute");
                            String[] arguments =
                            { budgetTransactionDTO.getAC8_TRANSACTION_TYPE(), "null", "null" };
                            ERPCoreUtility.addResultCode(ERPTransactionsTypes.BUDGET_EXECUTION_CODE.TX_RECORD_NOT_FOUND,messages,arguments,true);
                            return messages;
                        }
                    }
                }
            }

            if (messages.isEmpty())
            {
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null);
            }
            return messages;
        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
    }

    public List<MessageDTO> createExtraAmountFromProgFutureYR(Connection connection, BudgetTransactionDTO budgetTransactionDTO) throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO,Set reasonCode ) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.PROGRAM_FUTURE_EXTRA_APPROVED);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }
            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public List<MessageDTO> execExtraAmountFromProgFutureYR(Connection connection, String transactionSetId) throws ERPException
    {

        log.info("extraAmountForProgFutureYr called.");

        CoaMoiDTO coaMoi = new CoaMoiDTO();
        CoaMoiDTO coaMoiDTO = new CoaMoiDTO();
        COADepartmentDTO coaDepartmentDTO = new COADepartmentDTO();
        ProgramDistributionDTO programDistributionDTO = new ProgramDistributionDTO();
        ProgramDistributionDao programDistributionDao = new ProgramDistributionDao();
        ProgramYearsDao programYearsDao = new ProgramYearsDao();

        BigDecimal extraApprovedAmount = new BigDecimal(0);
        String fiscalYear = null;
        String minCode = null;
        String accountNum = null;
        String accountSubNum = null;
        String transactionType = null;
        String transactionStatus = null;
        String departmentId = null;
        String programRefNumber = null;
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "( called.");
        }

        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            Set<BudgetTransactionDTO> budgetTransactionCollection = new HashSet<BudgetTransactionDTO>();
            BudgetDetailsDTO budgetDetailsDTO = new BudgetDetailsDTO();

            budgetTransactionCollection = budgetAllocationDao.readBudgetTransaction(connection,BudgetTransactionDTO.class.newInstance(),transactionSetId,false);

            for (BudgetTransactionDTO budgetTransactionDTO : budgetTransactionCollection)
            {

                transactionType = budgetTransactionDTO.getAC8_TRANSACTION_TYPE();
                transactionStatus = budgetTransactionDTO.getAC8_TRANSACTION_STATUS();
                fiscalYear = budgetTransactionDTO.getAC8_FISCAL_YEAR();
                minCode = budgetTransactionDTO.getAC8_ACCOUNT_MINISTRY_NUMBER();
                accountNum = budgetTransactionDTO.getAC8_ACCOUNT_NUMBER();
                accountSubNum = budgetTransactionDTO.getAC8_ACCOUNT_SUB_NUMBER();
                departmentId = budgetTransactionDTO.getAC8_DEPARTMENT();
                extraApprovedAmount = budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT();
                programRefNumber = budgetTransactionDTO.getAC8_PROGRAM_REF_NUMBER().trim();

                coaMoi.setAC0_FISCAL_YEAR(fiscalYear);
                coaMoi.setAC0_ACCOUNT_MINISTRY_NUMBER(minCode);
                coaMoi.setAC0_ACCOUNT_NUMBER(accountNum);
                coaMoi.setAC0_ACCOUNT_SUB_NUMBER(accountSubNum);
                coaMoi.setAC0_EXTRA_APPROVED(extraApprovedAmount);

                coaMoiDTO = budgetAllocationDao.readBudgetAllocation(connection,coaMoi,false);

                coaDepartmentDTO = budgetAllocationDao.readDepartmentDetails(connection,budgetTransactionDTO);

                programDistributionDTO = programDistributionDao.readProgramDistribution(connection,minCode,accountNum,accountSubNum,fiscalYear,
                        programRefNumber,departmentId,false);

                budgetDetailsDTO = budgetAllocationDao.readBudgetDetails(connection,fiscalYear,minCode,accountNum,accountSubNum,departmentId,programRefNumber,
                        false);

                if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
                {
                    if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.PROGRAM_FUTURE_EXTRA_APPROVED))
                    {
                        if (coaMoiDTO != null && coaDepartmentDTO != null && programDistributionDTO != null)
                        {
                            programDistributionDao.updateProgramDistribution(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);
                            programYearsDao.updateProgramYears(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);
                            // This update statement ('POSTED') is not present previously
                            budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO);
                        }
                        else
                        {
                            log.info("Record not found during execute");
                            String[] arguments =
                            { budgetTransactionDTO.getAC8_TRANSACTION_TYPE(), "null", "null" };
                            ERPCoreUtility.addResultCode(ERPTransactionsTypes.BUDGET_EXECUTION_CODE.TX_RECORD_NOT_FOUND,messages,arguments,true);
                            return messages;
                        }
                    }
                }
            }

            if (messages.isEmpty())
            {
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null);
            }
            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
    }

    public List<MessageDTO> createExtraAmountFromMofForProgCurrentYR(Connection connection, BudgetTransactionDTO budgetTransactionDTO) throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.EXTRA_APPROVED_PROGRAM_MOF);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }
            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public List<MessageDTO> execExtraAmountFromMofForProgCurrentYR(Connection connection, String transactionSetId) throws ERPException
    {
        CoaMoiDTO coaMoi = new CoaMoiDTO();
        CoaMoiDTO coaMoiDTO = new CoaMoiDTO();
        COADepartmentDTO coaDepartmentDTO = new COADepartmentDTO();
        ProgramDistributionDTO programDistributionDTO = new ProgramDistributionDTO();
        ProgramDistributionDao programDistributionDao = new ProgramDistributionDao();
        ProgramYearsDao programYearsDao = new ProgramYearsDao();
        ProgramDao programDao = new ProgramDao();

        BigDecimal extraApprovedAmount = new BigDecimal(0);
        BigDecimal departmentFreeBalance = new BigDecimal(0);
        BigDecimal coaMoifreeBalance = new BigDecimal(0);
        BigDecimal budgetDetailsFreeBalance = new BigDecimal(0);
        String fiscalYear = null;
        String minCode = null;
        String accountNum = null;
        String accountSubNum = null;
        String transactionType = null;
        String transactionStatus = null;
        String departmentId = null;
        String programRefNumber = null;
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();
        if (log.isInfoEnabled())
        {
            log.info(methodName + "( called.");
        }
        int count = 0;

        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            Set<BudgetTransactionDTO> budgetTransactionCollection = new HashSet<BudgetTransactionDTO>();
            BudgetDetailsDTO budgetDetailsDTO = new BudgetDetailsDTO();

            budgetTransactionCollection = budgetAllocationDao.readBudgetTransaction(connection,BudgetTransactionDTO.class.newInstance(),transactionSetId,false);

            for (BudgetTransactionDTO budgetTransactionDTO : budgetTransactionCollection)
            {

                transactionType = budgetTransactionDTO.getAC8_TRANSACTION_TYPE();
                transactionStatus = budgetTransactionDTO.getAC8_TRANSACTION_STATUS();
                fiscalYear = budgetTransactionDTO.getAC8_FISCAL_YEAR();
                minCode = budgetTransactionDTO.getAC8_ACCOUNT_MINISTRY_NUMBER();
                accountNum = budgetTransactionDTO.getAC8_ACCOUNT_NUMBER();
                accountSubNum = budgetTransactionDTO.getAC8_ACCOUNT_SUB_NUMBER();
                departmentId = budgetTransactionDTO.getAC8_DEPARTMENT();
                extraApprovedAmount = budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT();
                programRefNumber = budgetTransactionDTO.getAC8_PROGRAM_REF_NUMBER().trim();

                programDistributionDTO = programDistributionDao.readProgramDistribution(connection,minCode,accountNum,accountSubNum,fiscalYear,
                        programRefNumber,departmentId,false);
                coaMoi.setAC0_FISCAL_YEAR(fiscalYear);
                coaMoi.setAC0_ACCOUNT_MINISTRY_NUMBER(minCode);
                coaMoi.setAC0_ACCOUNT_NUMBER(accountNum);
                coaMoi.setAC0_ACCOUNT_SUB_NUMBER(accountSubNum);
                coaMoi.setAC0_EXTRA_APPROVED(extraApprovedAmount);

                coaMoiDTO = budgetAllocationDao.readBudgetAllocation(connection,coaMoi,false);

                coaDepartmentDTO = budgetAllocationDao.readDepartmentDetails(connection,budgetTransactionDTO);

                budgetDetailsDTO = budgetAllocationDao.readBudgetDetails(connection,fiscalYear,minCode,accountNum,accountSubNum,departmentId,programRefNumber,
                        true);

                if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
                {
                    if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.EXTRA_APPROVED_PROGRAM_MOF))
                    {
                        if (coaMoiDTO != null && coaDepartmentDTO != null)
                        {
                            budgetDetailsFreeBalance = budgetDetailsDTO.getAC3_AMOUNT_APPROVED().add(budgetDetailsDTO.getAC3_PV_CREDIT_TOTAL())
                                    .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_COMMITMENT())
                                    .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_OBLIGATION()).subtract(budgetDetailsDTO.getAC3_PV_DEBIT_TOTAL());

                            budgetDetailsFreeBalance = budgetDetailsFreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                            budgetDetailsDTO.setAC3_AMOUNT_APPROVED(budgetDetailsDTO.getAC3_AMOUNT_APPROVED().add(
                                    budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            budgetDetailsDTO.setAC3_FREE_BALANCE(budgetDetailsFreeBalance);

                            count = budgetAllocationDao.updateBudgetDetails(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType); // Update Budget

                            if (count > 0)
                            {
                                departmentFreeBalance = coaDepartmentDTO.getAC2_APPROVED().add(coaDepartmentDTO.getAC2_EXTRA_APPROVED())
                                        .add(coaDepartmentDTO.getAC2_TRANSFERED_TO()).add(coaDepartmentDTO.getAC2_PV_CREDIT_TOTAL())
                                        .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_COMMITMENT())
                                        .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaDepartmentDTO.getAC2_PV_DEBIT_TOTAL())
                                        .subtract(coaDepartmentDTO.getAC2_TRANSFERED_FROM());

                                departmentFreeBalance = departmentFreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                                coaDepartmentDTO.setAC2_EXTRA_APPROVED(coaDepartmentDTO.getAC2_EXTRA_APPROVED().add(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                coaDepartmentDTO.setAC2_PROGRAM_APPROVED(coaDepartmentDTO.getAC2_PROGRAM_APPROVED().add(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                coaDepartmentDTO.setAC2_FREE_BALANCE(departmentFreeBalance);

                                budgetAllocationDao.updateDepartmentDetails(connection,budgetTransactionDTO,budgetDetailsDTO,coaDepartmentDTO,transactionType);

                            }
                            coaMoifreeBalance = coaMoiDTO.getAC0_APPROVED().add(coaMoiDTO.getAC0_EXTRA_APPROVED()).add(coaMoiDTO.getAC0_TRANSFERED_TO())
                                    .add(coaMoiDTO.getAC0_PV_CREDIT_TOTAL()).subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_COMMITMENT())
                                    .subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaMoiDTO.getAC0_PV_DEBIT_TOTAL())
                                    .subtract(coaMoiDTO.getAC0_TRANSFERED_FROM());

                            coaMoifreeBalance = coaMoifreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                            coaMoiDTO.setAC0_EXTRA_APPROVED(coaMoiDTO.getAC0_EXTRA_APPROVED().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            coaMoiDTO.setAC0_PROGRAM_APPROVED(coaMoiDTO.getAC0_PROGRAM_APPROVED().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            coaMoiDTO.setAC0_FREE_BALANCE(coaMoifreeBalance);

                            budgetAllocationDao.updateCoaMoi(connection,budgetTransactionDTO,coaMoiDTO,transactionType); // Update COA_MOI

                        }
                        else
                        {
                            log.info("Record not found in BUDGET_DETAILS during execute");
                            String[] arguments =
                            { budgetTransactionDTO.getAC8_TRANSACTION_TYPE(), "null", "null" };
                            ERPCoreUtility.addResultCode(ERPTransactionsTypes.BUDGET_EXECUTION_CODE.TX_RECORD_NOT_FOUND,messages,arguments,true);
                            return messages;
                        }
                        if (programDistributionDTO != null)
                        {
                            budgetTransactionDTO.setAC8_ACCOUNT_NUMBER(accountNum);
                            budgetTransactionDTO.setAC8_ACCOUNT_SUB_NUMBER(accountSubNum);
                            // Update Program Distribution
                            programDistributionDao.updateProgramDistribution(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);

                            programYearsDao.updateProgramYears(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType); // Update PgmYrs
                            programDao.updateProgram(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType); // Update PROGRAM
                        }
                        budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO);
                    }
                }
            }

            if (messages.isEmpty())
            {
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null);
            }
            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
    }

    public List<MessageDTO> createExtraAmountForDepartment(Connection connection, BudgetTransactionDTO budgetTransactionDTO) throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.EXTRA_APPROVED_DEPARTMENT);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }
            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public List<MessageDTO> execExtraAmountForDepartment(Connection connection, String transactionSetId) throws ERPException
    {
        CoaMoiDTO coaMoi = new CoaMoiDTO();
        CoaMoiDTO coaMoiDTO = new CoaMoiDTO();
        COADepartmentDTO coaDepartmentDTO = new COADepartmentDTO();

        BigDecimal extraApprovedAmount = new BigDecimal(0);
        BigDecimal coaMoifreeBalance = new BigDecimal(0);
        BigDecimal departmentFreeBalance = new BigDecimal(0);
        BigDecimal budgetDetailsFreeBalance = new BigDecimal(0);
        String fiscalYear = null;
        String minCode = null;
        String accountNum = null;
        String accountSubNum = null;
        String transactionType = null;
        String transactionStatus = null;
        String departmentId = null;
        String programRefNumber = null;
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();
        if (log.isInfoEnabled())
        {
            log.info(methodName + "( called.");
        }
        int count = 0;

        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            Set<BudgetTransactionDTO> budgetTransactionCollection = new HashSet<BudgetTransactionDTO>();
            BudgetDetailsDTO budgetDetailsDTO = new BudgetDetailsDTO();

            budgetTransactionCollection = budgetAllocationDao.readBudgetTransaction(connection,BudgetTransactionDTO.class.newInstance(),transactionSetId,false);

            for (BudgetTransactionDTO budgetTransactionDTO : budgetTransactionCollection)
            {

                transactionType = budgetTransactionDTO.getAC8_TRANSACTION_TYPE();
                transactionStatus = budgetTransactionDTO.getAC8_TRANSACTION_STATUS();
                fiscalYear = budgetTransactionDTO.getAC8_FISCAL_YEAR();
                minCode = budgetTransactionDTO.getAC8_ACCOUNT_MINISTRY_NUMBER();
                accountNum = budgetTransactionDTO.getAC8_ACCOUNT_NUMBER();
                accountSubNum = budgetTransactionDTO.getAC8_ACCOUNT_SUB_NUMBER();
                departmentId = budgetTransactionDTO.getAC8_DEPARTMENT();
                extraApprovedAmount = budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT();
                programRefNumber = budgetTransactionDTO.getAC8_PROGRAM_REF_NUMBER().trim();

                coaMoi.setAC0_FISCAL_YEAR(fiscalYear);
                coaMoi.setAC0_ACCOUNT_MINISTRY_NUMBER(minCode);
                coaMoi.setAC0_ACCOUNT_NUMBER(accountNum);
                coaMoi.setAC0_ACCOUNT_SUB_NUMBER(accountSubNum);
                coaMoi.setAC0_EXTRA_APPROVED(extraApprovedAmount);

                coaMoiDTO = budgetAllocationDao.readBudgetAllocation(connection,coaMoi,false);

                coaDepartmentDTO = budgetAllocationDao.readDepartmentDetails(connection,budgetTransactionDTO);

                budgetDetailsDTO = budgetAllocationDao.readBudgetDetails(connection,fiscalYear,minCode,accountNum,accountSubNum,departmentId,programRefNumber,
                        true);

                if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
                {
                    if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.EXTRA_APPROVED_DEPARTMENT))
                    {
                        if (coaMoiDTO != null && coaDepartmentDTO != null && programRefNumber.equals("0"))
                        {
                            budgetDetailsFreeBalance = budgetDetailsDTO.getAC3_AMOUNT_APPROVED().add(budgetDetailsDTO.getAC3_PV_CREDIT_TOTAL())
                                    .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_COMMITMENT())
                                    .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_OBLIGATION()).subtract(budgetDetailsDTO.getAC3_PV_DEBIT_TOTAL());

                            budgetDetailsFreeBalance = budgetDetailsFreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                            budgetDetailsDTO.setAC3_AMOUNT_APPROVED(budgetDetailsDTO.getAC3_AMOUNT_APPROVED().add(
                                    budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            budgetDetailsDTO.setAC3_FREE_BALANCE(budgetDetailsFreeBalance);

                            // Update BudgetDetails
                            count = budgetAllocationDao.updateBudgetDetails(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);

                            if (count > 0)
                            {
                                departmentFreeBalance = coaDepartmentDTO.getAC2_APPROVED().add(coaDepartmentDTO.getAC2_EXTRA_APPROVED())
                                        .add(coaDepartmentDTO.getAC2_TRANSFERED_TO()).add(coaDepartmentDTO.getAC2_PV_CREDIT_TOTAL())
                                        .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_COMMITMENT())
                                        .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaDepartmentDTO.getAC2_PV_DEBIT_TOTAL())
                                        .subtract(coaDepartmentDTO.getAC2_TRANSFERED_FROM());

                                departmentFreeBalance = departmentFreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                                coaDepartmentDTO.setAC2_EXTRA_APPROVED(coaDepartmentDTO.getAC2_EXTRA_APPROVED().add(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                coaDepartmentDTO.setAC2_NON_PROGRAM_APPROVED(coaDepartmentDTO.getAC2_NON_PROGRAM_APPROVED().add(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                coaDepartmentDTO.setAC2_FREE_BALANCE(departmentFreeBalance);

                                budgetAllocationDao.updateDepartmentDetails(connection,budgetTransactionDTO,budgetDetailsDTO,coaDepartmentDTO,transactionType);

                            }

                            coaMoifreeBalance = coaMoiDTO.getAC0_APPROVED().add(coaMoiDTO.getAC0_EXTRA_APPROVED()).add(coaMoiDTO.getAC0_TRANSFERED_TO())
                                    .add(coaMoiDTO.getAC0_PV_CREDIT_TOTAL()).subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_COMMITMENT())
                                    .subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaMoiDTO.getAC0_PV_DEBIT_TOTAL())
                                    .subtract(coaMoiDTO.getAC0_TRANSFERED_FROM());

                            coaMoifreeBalance = coaMoifreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                            coaMoiDTO.setAC0_EXTRA_APPROVED(coaMoiDTO.getAC0_EXTRA_APPROVED().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            coaMoiDTO.setAC0_FREE_BALANCE(coaMoifreeBalance);

                            budgetAllocationDao.updateCoaMoi(connection,budgetTransactionDTO,coaMoiDTO,transactionType); // Update COA_MOI

                            budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO);
                        }

                        else
                        {
                            log.info("Transaction record not found during execute");
                            String[] arguments =
                            { budgetTransactionDTO.getAC8_TRANSACTION_TYPE(), "null", "null" };
                            ERPCoreUtility.addResultCode(ERPTransactionsTypes.BUDGET_EXECUTION_CODE.TX_RECORD_NOT_FOUND,messages,arguments,true);
                            return messages;
                        }
                    }
                }
            }

            if (messages.isEmpty())
            {
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null);
            }
            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
    }

    public List<MessageDTO> createExtraAmountForBudgetClause(Connection connection, BudgetTransactionDTO budgetTransactionDTO) throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.RECEIVE_EXTRA_APPROVED);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }
            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public List<MessageDTO> execExtraAmountForBudgetClause(Connection connection, String transactionSetId) throws ERPException
    {
        CoaMoiDTO coaMoi = new CoaMoiDTO();
        CoaMoiDTO coaMoiDTO = new CoaMoiDTO();

        BigDecimal extraApprovedAmount = new BigDecimal(0);
        BigDecimal coaMoifreeBalance = new BigDecimal(0);
        String fiscalYear = null;
        String minCode = null;
        String accountNum = null;
        String accountSubNum = null;
        String transactionType = null;
        String transactionStatus = null;
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();
        if (log.isInfoEnabled())
        {
            log.info(methodName + "( called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();
            Set<BudgetTransactionDTO> budgetTransactionCollection = new HashSet<BudgetTransactionDTO>();
            budgetTransactionCollection = budgetAllocationDao.readBudgetTransaction(connection,BudgetTransactionDTO.class.newInstance(),transactionSetId,false);

            for (BudgetTransactionDTO budgetTransactionDTO : budgetTransactionCollection)
            {
                transactionType = budgetTransactionDTO.getAC8_TRANSACTION_TYPE();
                transactionStatus = budgetTransactionDTO.getAC8_TRANSACTION_STATUS();
                fiscalYear = budgetTransactionDTO.getAC8_FISCAL_YEAR();
                minCode = budgetTransactionDTO.getAC8_ACCOUNT_MINISTRY_NUMBER();
                accountNum = budgetTransactionDTO.getAC8_ACCOUNT_NUMBER();
                accountSubNum = budgetTransactionDTO.getAC8_ACCOUNT_SUB_NUMBER();
                extraApprovedAmount = budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT();

                coaMoi.setAC0_FISCAL_YEAR(fiscalYear);
                coaMoi.setAC0_ACCOUNT_MINISTRY_NUMBER(minCode);
                coaMoi.setAC0_ACCOUNT_NUMBER(accountNum);
                coaMoi.setAC0_ACCOUNT_SUB_NUMBER(accountSubNum);
                coaMoi.setAC0_EXTRA_APPROVED(extraApprovedAmount);

                coaMoiDTO = budgetAllocationDao.readBudgetAllocation(connection,coaMoi,false);

                if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
                {
                    if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.RECEIVE_EXTRA_APPROVED))
                    {
                        if (coaMoiDTO != null)
                        {
                            coaMoifreeBalance = coaMoiDTO.getAC0_APPROVED().add(coaMoiDTO.getAC0_EXTRA_APPROVED()).add(coaMoiDTO.getAC0_TRANSFERED_TO())
                                    .add(coaMoiDTO.getAC0_PV_CREDIT_TOTAL()).subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_COMMITMENT())
                                    .subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaMoiDTO.getAC0_PV_DEBIT_TOTAL())
                                    .subtract(coaMoiDTO.getAC0_TRANSFERED_FROM());

                            coaMoifreeBalance = coaMoifreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                            coaMoiDTO.setAC0_EXTRA_APPROVED(coaMoiDTO.getAC0_EXTRA_APPROVED().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            coaMoiDTO.setAC0_FREE_BALANCE(coaMoifreeBalance);
                            coaMoiDTO.setAC0_NON_DISTRIBUTED(coaMoiDTO.getAC0_NON_DISTRIBUTED().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));

                            budgetAllocationDao.updateCoaMoi(connection,budgetTransactionDTO,coaMoiDTO,transactionType); // Update COA_MOI

                            budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO);
                        }
                    }
                }
            }

            if (messages.isEmpty())
            {
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null);
            }
            return messages;
        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
    }

    public List<MessageDTO> createExtraFundFromFutureYRToCurrentYR(Connection connection, BudgetTransactionDTO budgetTransactionDTO) throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();
        List<MessageDTO> subMessages = null;

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO) called.");
        }
        try
        {
            // Create a record in TAC8_ BUDGET_TRANSACTION table
            budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");

            String transactionId = UUID.randomUUID().toString().replaceAll("-","");
            budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

            // CHECK DUPLICATE RECORD
            // budgetAllocationDao.checkDuplicateRecord(connection,budgetTransactionDTO,reasonCode);

            if (messages.isEmpty())
            {
                // TransactionSetID is same for both the processes
                budgetTransactionDTO.setAC8_TRANSACTION_SET_ID(transactionId);

                // CREATE EXTRA AMOUNT FROM PROG FUTURE YR TRANSACTION_v1.0
                subMessages = createExtraAmountFromProgFutureYR(connection,budgetTransactionDTO);
                transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                // CHECK DUPLICATE RECORD
                // budgetAllocationDao.checkDuplicateRecord(connection,budgetTransactionDTO,reasonCode);

                if (messages.isEmpty() && subMessages.contains(ERPTransactionsTypes.MESSAGECODE.SUCCESS))
                {
                    // CREATE EXTRA AMOUNT FOR PROG CURRENT YR TRANSACTION_v1.0 //
                    subMessages = createExtraAmountForProgCurrentYR(connection,budgetTransactionDTO);

                    if (!subMessages.isEmpty() && subMessages.contains(ERPTransactionsTypes.MESSAGECODE.SUCCESS))
                    {
                        ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
                    }
                }
                else
                {
                    log.info("Errors existing in the earlier transaction");
                    String[] arguments =
                    { budgetTransactionDTO.getAC8_TRANSACTION_TYPE(), "null", "null" };
                    // Need to change the errorCode
                    ERPCoreUtility.addResultCode(ERPTransactionsTypes.BUDGET_EXECUTION_CODE.RECORD_ALREADY_EXISTS,messages,arguments,true);
                    return messages;
                }

                return messages;
            }
            else
            {
                log.info("Validation for Duplicate Record failed "); // this is for the posted condition
                String[] arguments =
                { budgetTransactionDTO.getAC8_TRANSACTION_TYPE(), "null", "null" };
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.BUDGET_EXECUTION_CODE.RECORD_ALREADY_EXISTS,messages,arguments,true);
                return messages;
            }

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public void execExtraFundFromFutureYRtoCurrentYR(Connection connection, String transactionSetId) throws ERPException
    {

        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        try
        {
            execExtraAmountFromProgFutureYR(connection,transactionSetId);
            execExtraAmountForProgCurrentYR(connection,transactionSetId);
        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
    }

    public List<MessageDTO> createTransferFromDeptToNonDistributedFund(Connection connection, BudgetTransactionDTO budgetTransactionDTO) throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.TRANSFER_FROM_DEPARTMENT_TO_NON_DISTRIBUTED);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }
            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public List<MessageDTO> createTransferFromNonDistributeFundToDept(Connection connection, BudgetTransactionDTO budgetTransactionDTO) throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.TRANSFER_TO_DEPARTMENT_FROM_NON_DISTRIBUTED);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }
            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    /**
     * This transaction contains 2 execute transactions 'TRANSFER_FROM_DEPARTMENT_TO_NON_DISTRIBUTED' and 'TRANSFER_TO_DEPARTMENT_FROM_NON_DISTRIBUTED'
     * 
     * @param connection
     * @param transactionSetId
     * @return
     * @throws ERPException
     */
    public List<MessageDTO> execTransferFromDepartmentToNonDistributed(Connection connection, String transactionSetId) throws ERPException
    {

        CoaMoiDTO coaMoi = new CoaMoiDTO();
        CoaMoiDTO coaMoiDTO = new CoaMoiDTO();
        COADepartmentDTO coaDepartmentDTO = new COADepartmentDTO();
        BigDecimal budgetDetailsFreeBalance = new BigDecimal(0);
        BigDecimal departmentFreeBalance = new BigDecimal(0);
        String fiscalYear = null;
        String minCode = null;
        String accountNum = null;
        String accountSubNum = null;
        String transactionType = null;
        String transactionStatus = null;
        String departmentId = null;
        String programRefNumber = null;
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "( called.");
        }
        int count = 0;

        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            Set<BudgetTransactionDTO> budgetTransactionCollection = new HashSet<BudgetTransactionDTO>();
            BudgetDetailsDTO budgetDetailsDTO = new BudgetDetailsDTO();

            budgetTransactionCollection = budgetAllocationDao.readBudgetTransaction(connection,BudgetTransactionDTO.class.newInstance(),transactionSetId,false);

            for (BudgetTransactionDTO budgetTransactionDTO : budgetTransactionCollection)
            {
                transactionType = budgetTransactionDTO.getAC8_TRANSACTION_TYPE();
                transactionStatus = budgetTransactionDTO.getAC8_TRANSACTION_STATUS();
                fiscalYear = budgetTransactionDTO.getAC8_FISCAL_YEAR();
                minCode = budgetTransactionDTO.getAC8_ACCOUNT_MINISTRY_NUMBER();
                accountNum = budgetTransactionDTO.getAC8_ACCOUNT_NUMBER();
                accountSubNum = budgetTransactionDTO.getAC8_ACCOUNT_SUB_NUMBER();
                departmentId = budgetTransactionDTO.getAC8_DEPARTMENT();

                programRefNumber = budgetTransactionDTO.getAC8_PROGRAM_REF_NUMBER().trim();

                coaMoi.setAC0_FISCAL_YEAR(fiscalYear);
                coaMoi.setAC0_ACCOUNT_MINISTRY_NUMBER(minCode);
                coaMoi.setAC0_ACCOUNT_NUMBER(accountNum);
                coaMoi.setAC0_ACCOUNT_SUB_NUMBER(accountSubNum);

                coaMoiDTO = budgetAllocationDao.readBudgetAllocation(connection,coaMoi,false);

                coaDepartmentDTO = budgetAllocationDao.readDepartmentDetails(connection,budgetTransactionDTO);

                budgetDetailsDTO = budgetAllocationDao.readBudgetDetails(connection,fiscalYear,minCode,accountNum,accountSubNum,departmentId,programRefNumber,
                        true);

                if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
                {
                    if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.TRANSFER_FROM_DEPARTMENT_TO_NON_DISTRIBUTED))
                    {
                        if (coaMoiDTO != null && coaDepartmentDTO != null && budgetDetailsDTO != null && programRefNumber.equals("0"))
                        {
                            budgetDetailsFreeBalance = budgetDetailsDTO.getAC3_AMOUNT_APPROVED().add(budgetDetailsDTO.getAC3_PV_CREDIT_TOTAL())
                                    .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_COMMITMENT())
                                    .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_OBLIGATION()).subtract(budgetDetailsDTO.getAC3_PV_DEBIT_TOTAL());

                            budgetDetailsFreeBalance = budgetDetailsFreeBalance.subtract(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                            budgetDetailsDTO.setAC3_AMOUNT_APPROVED(budgetDetailsDTO.getAC3_AMOUNT_APPROVED().subtract(
                                    budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            budgetDetailsDTO.setAC3_FREE_BALANCE(budgetDetailsFreeBalance);

                            // Update Budget Details
                            count = budgetAllocationDao.updateBudgetDetails(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);

                            if (count > 0)
                            {
                                departmentFreeBalance = coaDepartmentDTO.getAC2_APPROVED().add(coaDepartmentDTO.getAC2_EXTRA_APPROVED())
                                        .add(coaDepartmentDTO.getAC2_TRANSFERED_TO()).add(coaDepartmentDTO.getAC2_PV_CREDIT_TOTAL())
                                        .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_COMMITMENT())
                                        .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaDepartmentDTO.getAC2_PV_DEBIT_TOTAL())
                                        .subtract(coaDepartmentDTO.getAC2_TRANSFERED_FROM());

                                departmentFreeBalance = departmentFreeBalance.subtract(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                                coaDepartmentDTO.setAC2_TRANSFERED_FROM(coaDepartmentDTO.getAC2_TRANSFERED_FROM().add(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                coaDepartmentDTO.setAC2_NON_PROGRAM_APPROVED(coaDepartmentDTO.getAC2_NON_PROGRAM_APPROVED().subtract(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                coaDepartmentDTO.setAC2_FREE_BALANCE(departmentFreeBalance);

                                budgetAllocationDao.updateDepartmentDetails(connection,budgetTransactionDTO,budgetDetailsDTO,coaDepartmentDTO,transactionType);

                            }
                            coaMoiDTO.setAC0_NON_PROGRAM_APPROVED(coaMoiDTO.getAC0_NON_PROGRAM_APPROVED().subtract(
                                    budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            coaMoiDTO.setAC0_NON_DISTRIBUTED(coaMoiDTO.getAC0_NON_DISTRIBUTED().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));

                            budgetAllocationDao.updateCoaMoi(connection,budgetTransactionDTO,coaMoiDTO,transactionType); // Update COA_MOI

                            budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO);
                        }

                        else
                        {
                            log.info("Record not found in BUDGET_DETAILS during execute");
                            String[] arguments =
                            { budgetTransactionDTO.getAC8_TRANSACTION_TYPE(), "null", "null" };
                            ERPCoreUtility.addResultCode(ERPTransactionsTypes.BUDGET_EXECUTION_CODE.TX_RECORD_NOT_FOUND,messages,arguments,true);
                            return messages;
                        }
                    }
                }
                if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
                {
                    if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.TRANSFER_TO_DEPARTMENT_FROM_NON_DISTRIBUTED))
                    {
                        if (coaMoiDTO != null && coaDepartmentDTO != null && budgetDetailsDTO != null && programRefNumber.equals("0"))
                        {
                            budgetDetailsFreeBalance = budgetDetailsDTO.getAC3_AMOUNT_APPROVED().add(budgetDetailsDTO.getAC3_PV_CREDIT_TOTAL())
                                    .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_COMMITMENT())
                                    .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_OBLIGATION()).subtract(budgetDetailsDTO.getAC3_PV_DEBIT_TOTAL());

                            budgetDetailsFreeBalance = budgetDetailsFreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                            budgetDetailsDTO.setAC3_AMOUNT_APPROVED(budgetDetailsDTO.getAC3_AMOUNT_APPROVED().add(
                                    budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            budgetDetailsDTO.setAC3_FREE_BALANCE(budgetDetailsFreeBalance);

                            // Update Budget Details
                            count = budgetAllocationDao.updateBudgetDetails(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);

                            if (count > 0)
                            {
                                departmentFreeBalance = coaDepartmentDTO.getAC2_APPROVED().add(coaDepartmentDTO.getAC2_EXTRA_APPROVED())
                                        .add(coaDepartmentDTO.getAC2_TRANSFERED_TO()).add(coaDepartmentDTO.getAC2_PV_CREDIT_TOTAL())
                                        .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_COMMITMENT())
                                        .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaDepartmentDTO.getAC2_PV_DEBIT_TOTAL())
                                        .subtract(coaDepartmentDTO.getAC2_TRANSFERED_FROM());

                                departmentFreeBalance = departmentFreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                                coaDepartmentDTO.setAC2_TRANSFERED_TO(coaDepartmentDTO.getAC2_TRANSFERED_TO().add(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                coaDepartmentDTO.setAC2_NON_PROGRAM_APPROVED(coaDepartmentDTO.getAC2_NON_PROGRAM_APPROVED().add(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                coaDepartmentDTO.setAC2_FREE_BALANCE(departmentFreeBalance);

                                budgetAllocationDao.updateDepartmentDetails(connection,budgetTransactionDTO,budgetDetailsDTO,coaDepartmentDTO,transactionType);

                            }
                            coaMoiDTO
                                    .setAC0_NON_PROGRAM_APPROVED(coaMoiDTO.getAC0_NON_PROGRAM_APPROVED().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            coaMoiDTO.setAC0_NON_DISTRIBUTED(coaMoiDTO.getAC0_NON_DISTRIBUTED().subtract(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));

                            budgetAllocationDao.updateCoaMoi(connection,budgetTransactionDTO,coaMoiDTO,transactionType); // Update COA_MOI

                            budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO);
                        }

                        else
                        {
                            log.info("Record not found in BUDGET_DETAILS during execute");
                            String[] arguments =
                            { budgetTransactionDTO.getAC8_TRANSACTION_TYPE(), "null", "null" };
                            ERPCoreUtility.addResultCode(ERPTransactionsTypes.BUDGET_EXECUTION_CODE.TX_RECORD_NOT_FOUND,messages,arguments,true);
                            return messages;
                        }
                    }
                }
            }

            if (messages.isEmpty())
            {
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null);
            }
            return messages;
        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
    }

    public List<MessageDTO> createTransferFromProgToNonDistributedOfBudget(Connection connection, BudgetTransactionDTO budgetTransactionDTO)
            throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.TRANSFER_FROM_PROGRAM);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }
            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public List<MessageDTO> createTransferToProgFromNonDistributedOfBudget(Connection connection, BudgetTransactionDTO budgetTransactionDTO)
            throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.TRANSFER_TO_PROGRAM);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }

            return messages;
        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public List<MessageDTO> execTransferFromProgramToNonDistributed(Connection connection, String transactionSetId) throws ERPException
    {

        CoaMoiDTO coaMoi = new CoaMoiDTO();
        CoaMoiDTO coaMoiDTO = new CoaMoiDTO();
        COADepartmentDTO coaDepartmentDTO = new COADepartmentDTO();
        ProgramDistributionDTO programDistributionDTO = new ProgramDistributionDTO();
        ProgramDistributionDao programDistributionDao = new ProgramDistributionDao();
        ProgramYearsDao programYearsDao = new ProgramYearsDao();
        ProgramDao programDao = new ProgramDao();
        BigDecimal budgetDetailsFreeBalance = new BigDecimal(0);
        BigDecimal departmentFreeBalance = new BigDecimal(0);
        String fiscalYear = null;
        String minCode = null;
        String accountNum = null;
        String accountSubNum = null;
        String transactionType = null;
        String transactionStatus = null;
        String departmentId = null;
        String programRefNumber = null;
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "( called.");
        }
        int count = 0;

        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            Set<BudgetTransactionDTO> budgetTransactionCollection = new HashSet<BudgetTransactionDTO>();
            BudgetDetailsDTO budgetDetailsDTO = new BudgetDetailsDTO();

            budgetTransactionCollection = budgetAllocationDao.readBudgetTransaction(connection,BudgetTransactionDTO.class.newInstance(),transactionSetId,false);

            for (BudgetTransactionDTO budgetTransactionDTO : budgetTransactionCollection)
            {

                transactionType = budgetTransactionDTO.getAC8_TRANSACTION_TYPE();
                transactionStatus = budgetTransactionDTO.getAC8_TRANSACTION_STATUS();
                fiscalYear = budgetTransactionDTO.getAC8_FISCAL_YEAR();
                minCode = budgetTransactionDTO.getAC8_ACCOUNT_MINISTRY_NUMBER();
                accountNum = budgetTransactionDTO.getAC8_ACCOUNT_NUMBER();
                accountSubNum = budgetTransactionDTO.getAC8_ACCOUNT_SUB_NUMBER();
                departmentId = budgetTransactionDTO.getAC8_DEPARTMENT();
                programRefNumber = budgetTransactionDTO.getAC8_PROGRAM_REF_NUMBER().trim();

                coaMoi.setAC0_FISCAL_YEAR(fiscalYear);
                coaMoi.setAC0_ACCOUNT_MINISTRY_NUMBER(minCode);
                coaMoi.setAC0_ACCOUNT_NUMBER(accountNum);
                coaMoi.setAC0_ACCOUNT_SUB_NUMBER(accountSubNum);

                coaMoiDTO = budgetAllocationDao.readBudgetAllocation(connection,coaMoi,false);

                coaDepartmentDTO = budgetAllocationDao.readDepartmentDetails(connection,budgetTransactionDTO);

                programDistributionDTO = programDistributionDao.readProgramDistribution(connection,minCode,accountNum,accountSubNum,fiscalYear,
                        programRefNumber,departmentId,false);

                budgetDetailsDTO = budgetAllocationDao.readBudgetDetails(connection,fiscalYear,minCode,accountNum,accountSubNum,departmentId,programRefNumber,
                        true);

                if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
                {
                    if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.TRANSFER_FROM_PROGRAM))
                    {
                        if (coaMoiDTO != null && coaDepartmentDTO != null && budgetDetailsDTO != null && programDistributionDTO != null)
                        {

                            budgetDetailsFreeBalance = budgetDetailsDTO.getAC3_AMOUNT_APPROVED().add(budgetDetailsDTO.getAC3_PV_CREDIT_TOTAL())
                                    .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_COMMITMENT())
                                    .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_OBLIGATION()).subtract(budgetDetailsDTO.getAC3_PV_DEBIT_TOTAL());

                            budgetDetailsFreeBalance = budgetDetailsFreeBalance.subtract(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                            budgetDetailsDTO.setAC3_AMOUNT_APPROVED(budgetDetailsDTO.getAC3_AMOUNT_APPROVED().subtract(
                                    budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            budgetDetailsDTO.setAC3_FREE_BALANCE(budgetDetailsFreeBalance);

                            // Update Budget Details
                            count = budgetAllocationDao.updateBudgetDetails(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);

                            if (count > 0)
                            {
                                departmentFreeBalance = coaDepartmentDTO.getAC2_APPROVED().add(coaDepartmentDTO.getAC2_EXTRA_APPROVED())
                                        .add(coaDepartmentDTO.getAC2_TRANSFERED_TO()).add(coaDepartmentDTO.getAC2_PV_CREDIT_TOTAL())
                                        .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_COMMITMENT())
                                        .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaDepartmentDTO.getAC2_PV_DEBIT_TOTAL())
                                        .subtract(coaDepartmentDTO.getAC2_TRANSFERED_FROM());

                                departmentFreeBalance = departmentFreeBalance.subtract(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                                coaDepartmentDTO.setAC2_PROGRAM_APPROVED(coaDepartmentDTO.getAC2_PROGRAM_APPROVED().subtract(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                coaDepartmentDTO.setAC2_FREE_BALANCE(departmentFreeBalance);

                                budgetAllocationDao.updateDepartmentDetails(connection,budgetTransactionDTO,budgetDetailsDTO,coaDepartmentDTO,transactionType);

                            }

                            coaMoiDTO.setAC0_PROGRAM_APPROVED(coaMoiDTO.getAC0_PROGRAM_APPROVED().subtract(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            coaMoiDTO.setAC0_NON_DISTRIBUTED(coaMoiDTO.getAC0_NON_DISTRIBUTED().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));

                            budgetAllocationDao.updateCoaMoi(connection,budgetTransactionDTO,coaMoiDTO,transactionType); // Update COA_MOI

                            if (programDistributionDTO != null)
                            {
                                budgetTransactionDTO.setAC8_ACCOUNT_NUMBER(accountNum);
                                budgetTransactionDTO.setAC8_ACCOUNT_SUB_NUMBER(accountSubNum);
                                programDistributionDao.updateProgramDistribution(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);
                                programYearsDao.updateProgramYears(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);
                                programDao.updateProgram(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);
                            }
                            budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO);
                        }
                    }
                }
                if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
                {
                    if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.TRANSFER_TO_PROGRAM))
                    {
                        if (coaMoiDTO != null && coaDepartmentDTO != null && budgetDetailsDTO != null && programDistributionDTO != null)
                        {

                            budgetDetailsFreeBalance = budgetDetailsDTO.getAC3_AMOUNT_APPROVED().add(budgetDetailsDTO.getAC3_PV_CREDIT_TOTAL())
                                    .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_COMMITMENT())
                                    .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_OBLIGATION()).subtract(budgetDetailsDTO.getAC3_PV_DEBIT_TOTAL());

                            budgetDetailsFreeBalance = budgetDetailsFreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                            budgetDetailsDTO.setAC3_AMOUNT_APPROVED(budgetDetailsDTO.getAC3_AMOUNT_APPROVED().add(
                                    budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            budgetDetailsDTO.setAC3_FREE_BALANCE(budgetDetailsFreeBalance);

                            // Update Budget Details
                            count = budgetAllocationDao.updateBudgetDetails(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);

                            if (count > 0)
                            {
                                departmentFreeBalance = coaDepartmentDTO.getAC2_APPROVED().add(coaDepartmentDTO.getAC2_EXTRA_APPROVED())
                                        .add(coaDepartmentDTO.getAC2_TRANSFERED_TO()).add(coaDepartmentDTO.getAC2_PV_CREDIT_TOTAL())
                                        .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_COMMITMENT())
                                        .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaDepartmentDTO.getAC2_PV_DEBIT_TOTAL())
                                        .subtract(coaDepartmentDTO.getAC2_TRANSFERED_FROM());

                                departmentFreeBalance = departmentFreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                                coaDepartmentDTO.setAC2_PROGRAM_APPROVED(coaDepartmentDTO.getAC2_PROGRAM_APPROVED().add(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                coaDepartmentDTO.setAC2_FREE_BALANCE(departmentFreeBalance);

                                budgetAllocationDao.updateDepartmentDetails(connection,budgetTransactionDTO,budgetDetailsDTO,coaDepartmentDTO,transactionType);

                            }

                            coaMoiDTO.setAC0_PROGRAM_APPROVED(coaMoiDTO.getAC0_PROGRAM_APPROVED().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            coaMoiDTO.setAC0_NON_DISTRIBUTED(coaMoiDTO.getAC0_NON_DISTRIBUTED().subtract(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));

                            budgetAllocationDao.updateCoaMoi(connection,budgetTransactionDTO,coaMoiDTO,transactionType); // Update COA_MOI

                            if (programDistributionDTO != null)
                            {
                                budgetTransactionDTO.setAC8_ACCOUNT_NUMBER(accountNum);
                                budgetTransactionDTO.setAC8_ACCOUNT_SUB_NUMBER(accountSubNum);
                                programDistributionDao.updateProgramDistribution(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);
                                programYearsDao.updateProgramYears(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);
                                programDao.updateProgram(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);
                            }
                            budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO);
                        }
                    }
                }
            }

            if (messages.isEmpty())
            {
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null);
            }
            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
    }

    // CREATE TRANSFER FROM BUDGET CLAUSE TRANSACTION
    /**
     * This process will be called whenever amount is transferred from the free balance of a Budget clause. This process will create a record in the
     * TAC8_BUDGET_TRANSACTION table using the input which is passed to this process. * table using the input which is passed to this process. Transaction
     * Affects MOI, Department and Program Level.
     * 
     * */

    public List<MessageDTO> createTransferFreeBalanceFromBudgetClause(Connection connection, BudgetTransactionDTO budgetTransactionDTO) throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.TRANSFER_FREE_BAL_FROM_BUDGET);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }

            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public List<MessageDTO> execTransferFreeBalanceFromBudgetClause(Connection connection, String transactionSetId) throws ERPException
    {

        CoaMoiDTO coaMoi = new CoaMoiDTO();
        CoaMoiDTO coaMoiDTO = new CoaMoiDTO();
        COADepartmentDTO coaDepartmentDTO = new COADepartmentDTO();
        ProgramDistributionDTO programDistributionDTO = new ProgramDistributionDTO();
        ProgramDistributionDao programDistributionDao = new ProgramDistributionDao();
        ProgramYearsDao programYearsDao = new ProgramYearsDao();
        ProgramDao programDao = new ProgramDao();

        BigDecimal extraApprovedAmount = new BigDecimal(0);
        BigDecimal budgetDetailsFreeBalance = new BigDecimal(0);
        BigDecimal departmentFreeBalance = new BigDecimal(0);
        BigDecimal coaMoifreeBalance = new BigDecimal(0);
        String fiscalYear = null;
        String minCode = null;
        String accountNum = null;
        String accountSubNum = null;
        String transactionType = null;
        String transactionStatus = null;
        String departmentId = null;
        String programRefNumber = null;
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "( called.");
        }
        int count = 0;

        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();
            Set<BudgetTransactionDTO> budgetTransactionCollection = new HashSet<BudgetTransactionDTO>();
            BudgetDetailsDTO budgetDetailsDTO = new BudgetDetailsDTO();
            budgetTransactionCollection = budgetAllocationDao.readBudgetTransaction(connection,BudgetTransactionDTO.class.newInstance(),transactionSetId,false);

            for (BudgetTransactionDTO budgetTransactionDTO : budgetTransactionCollection)
            {

                transactionType = budgetTransactionDTO.getAC8_TRANSACTION_TYPE();
                transactionStatus = budgetTransactionDTO.getAC8_TRANSACTION_STATUS();
                fiscalYear = budgetTransactionDTO.getAC8_FISCAL_YEAR();
                minCode = budgetTransactionDTO.getAC8_ACCOUNT_MINISTRY_NUMBER();
                accountNum = budgetTransactionDTO.getAC8_ACCOUNT_NUMBER();
                accountSubNum = budgetTransactionDTO.getAC8_ACCOUNT_SUB_NUMBER();
                departmentId = budgetTransactionDTO.getAC8_DEPARTMENT();
                extraApprovedAmount = budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT();
                programRefNumber = budgetTransactionDTO.getAC8_PROGRAM_REF_NUMBER().trim();

                programDistributionDTO = programDistributionDao.readProgramDistribution(connection,minCode,accountNum,accountSubNum,fiscalYear,
                        programRefNumber,departmentId,false);

                coaMoi.setAC0_FISCAL_YEAR(fiscalYear);
                coaMoi.setAC0_ACCOUNT_MINISTRY_NUMBER(minCode);
                coaMoi.setAC0_ACCOUNT_NUMBER(accountNum);
                coaMoi.setAC0_ACCOUNT_SUB_NUMBER(accountSubNum);
                coaMoi.setAC0_EXTRA_APPROVED(extraApprovedAmount);

                coaMoiDTO = budgetAllocationDao.readBudgetAllocation(connection,coaMoi,false);

                coaDepartmentDTO = budgetAllocationDao.readDepartmentDetails(connection,budgetTransactionDTO);

                budgetDetailsDTO = budgetAllocationDao.readBudgetDetails(connection,fiscalYear,minCode,accountNum,accountSubNum,departmentId,programRefNumber,
                        true);

                if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
                {
                    if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.TRANSFER_FREE_BAL_FROM_BUDGET))
                    {
                        if (coaMoiDTO != null && coaDepartmentDTO != null)
                        {
                            budgetDetailsFreeBalance = budgetDetailsDTO.getAC3_AMOUNT_APPROVED().add(budgetDetailsDTO.getAC3_PV_CREDIT_TOTAL())
                                    .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_COMMITMENT())
                                    .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_OBLIGATION()).subtract(budgetDetailsDTO.getAC3_PV_DEBIT_TOTAL());

                            budgetDetailsFreeBalance = budgetDetailsFreeBalance.subtract(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                            budgetDetailsDTO.setAC3_AMOUNT_APPROVED(budgetDetailsDTO.getAC3_AMOUNT_APPROVED().subtract(
                                    budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            budgetDetailsDTO.setAC3_FREE_BALANCE(budgetDetailsFreeBalance);

                            // Update Budget Details
                            count = budgetAllocationDao.updateBudgetDetails(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);

                            if (count > 0)
                            {
                                departmentFreeBalance = coaDepartmentDTO.getAC2_APPROVED().add(coaDepartmentDTO.getAC2_EXTRA_APPROVED())
                                        .add(coaDepartmentDTO.getAC2_TRANSFERED_TO()).add(coaDepartmentDTO.getAC2_PV_CREDIT_TOTAL())
                                        .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_COMMITMENT())
                                        .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaDepartmentDTO.getAC2_PV_DEBIT_TOTAL())
                                        .subtract(coaDepartmentDTO.getAC2_TRANSFERED_FROM());

                                departmentFreeBalance = departmentFreeBalance.subtract(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                                coaDepartmentDTO.setAC2_TRANSFERED_FROM(coaDepartmentDTO.getAC2_TRANSFERED_FROM().add(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                if (!programRefNumber.equals("0"))
                                {
                                    coaDepartmentDTO.setAC2_PROGRAM_APPROVED(coaDepartmentDTO.getAC2_PROGRAM_APPROVED().subtract(
                                            budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                }
                                else
                                {
                                    coaDepartmentDTO.setAC2_NON_PROGRAM_APPROVED(coaDepartmentDTO.getAC2_NON_PROGRAM_APPROVED().subtract(
                                            budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                }
                                coaDepartmentDTO.setAC2_FREE_BALANCE(departmentFreeBalance);

                                budgetAllocationDao.updateDepartmentDetails(connection,budgetTransactionDTO,budgetDetailsDTO,coaDepartmentDTO,transactionType);

                            }

                            coaMoifreeBalance = coaMoiDTO.getAC0_APPROVED().add(coaMoiDTO.getAC0_EXTRA_APPROVED()).add(coaMoiDTO.getAC0_TRANSFERED_TO())
                                    .add(coaMoiDTO.getAC0_PV_CREDIT_TOTAL()).subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_COMMITMENT())
                                    .subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaMoiDTO.getAC0_PV_DEBIT_TOTAL())
                                    .subtract(coaMoiDTO.getAC0_TRANSFERED_FROM());

                            coaMoifreeBalance = coaMoifreeBalance.subtract(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                            coaMoiDTO.setAC0_TRANSFERED_FROM(coaMoiDTO.getAC0_TRANSFERED_FROM().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            if (!programRefNumber.equals("0"))
                            {
                                coaMoiDTO.setAC0_PROGRAM_APPROVED(coaMoiDTO.getAC0_PROGRAM_APPROVED()
                                        .subtract(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            }
                            else
                            {
                                coaMoiDTO.setAC0_NON_PROGRAM_APPROVED(coaMoiDTO.getAC0_NON_PROGRAM_APPROVED().subtract(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            }
                            coaMoiDTO.setAC0_FREE_BALANCE(coaMoifreeBalance);

                            budgetAllocationDao.updateCoaMoi(connection,budgetTransactionDTO,coaMoiDTO,transactionType); // Update COA_MOI

                            if (programDistributionDTO != null)
                            {
                                budgetTransactionDTO.setAC8_ACCOUNT_NUMBER(accountNum);
                                budgetTransactionDTO.setAC8_ACCOUNT_SUB_NUMBER(accountSubNum);
                                programDistributionDao.updateProgramDistribution(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);
                                programYearsDao.updateProgramYears(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);
                                programDao.updateProgram(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);
                            }
                            budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO);
                        }
                    }
                }
            }

            if (messages.isEmpty())
            {
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null);
            }
            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
    }

    // CREATE TRANSFER TO BUDGET CLAUSE TRANSACTION
    /**
     * This process will be called whenever amount is transferred from the free balance of a Budget clause. This process will create a record in the
     * TAC8_BUDGET_TRANSACTION table using the input which is passed to this process. * table using the input which is passed to this process. Transaction
     * Affects MOI, Department and Program Level.
     * */

    public List<MessageDTO> createTransferFreeBalanceToBudgetClause(Connection connection, BudgetTransactionDTO budgetTransactionDTO) throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.TRANSFER_FREE_BAL_TO_BUDGET);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }

            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public List<MessageDTO> execTransferFreeBalanceToBudgetClause(Connection connection, String transactionSetId) throws ERPException
    {

        CoaMoiDTO coaMoi = new CoaMoiDTO();
        CoaMoiDTO coaMoiDTO = new CoaMoiDTO();
        COADepartmentDTO coaDepartmentDTO = new COADepartmentDTO();
        ProgramDistributionDTO programDistributionDTO = new ProgramDistributionDTO();
        ProgramDistributionDao programDistributionDao = new ProgramDistributionDao();
        ProgramYearsDao programYearsDao = new ProgramYearsDao();
        ProgramDao programDao = new ProgramDao();

        BigDecimal extraApprovedAmount = new BigDecimal(0);
        BigDecimal budgetDetailsFreeBalance = new BigDecimal(0);
        BigDecimal departmentFreeBalance = new BigDecimal(0);
        BigDecimal coaMoifreeBalance = new BigDecimal(0);
        String fiscalYear = null;
        String minCode = null;
        String accountNum = null;
        String accountSubNum = null;
        String transactionType = null;
        String transactionStatus = null;
        String departmentId = null;
        String programRefNumber = null;
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();
        if (log.isInfoEnabled())
        {
            log.info(methodName + "( called.");
        }
        int count = 0;

        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            Set<BudgetTransactionDTO> budgetTransactionCollection = new HashSet<BudgetTransactionDTO>();
            BudgetDetailsDTO budgetDetailsDTO = new BudgetDetailsDTO();

            budgetTransactionCollection = budgetAllocationDao.readBudgetTransaction(connection,BudgetTransactionDTO.class.newInstance(),transactionSetId,false);

            for (BudgetTransactionDTO budgetTransactionDTO : budgetTransactionCollection)
            {

                transactionType = budgetTransactionDTO.getAC8_TRANSACTION_TYPE();
                transactionStatus = budgetTransactionDTO.getAC8_TRANSACTION_STATUS();
                fiscalYear = budgetTransactionDTO.getAC8_FISCAL_YEAR();
                minCode = budgetTransactionDTO.getAC8_ACCOUNT_MINISTRY_NUMBER();
                accountNum = budgetTransactionDTO.getAC8_ACCOUNT_NUMBER();
                accountSubNum = budgetTransactionDTO.getAC8_ACCOUNT_SUB_NUMBER();
                departmentId = budgetTransactionDTO.getAC8_DEPARTMENT();
                extraApprovedAmount = budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT();
                programRefNumber = budgetTransactionDTO.getAC8_PROGRAM_REF_NUMBER().trim();

                programDistributionDTO = programDistributionDao.readProgramDistribution(connection,minCode,accountNum,accountSubNum,fiscalYear,
                        programRefNumber,departmentId,false);

                coaMoi.setAC0_FISCAL_YEAR(fiscalYear);
                coaMoi.setAC0_ACCOUNT_MINISTRY_NUMBER(minCode);
                coaMoi.setAC0_ACCOUNT_NUMBER(accountNum);
                coaMoi.setAC0_ACCOUNT_SUB_NUMBER(accountSubNum);
                coaMoi.setAC0_EXTRA_APPROVED(extraApprovedAmount);

                coaMoiDTO = budgetAllocationDao.readBudgetAllocation(connection,coaMoi,false);

                coaDepartmentDTO = budgetAllocationDao.readDepartmentDetails(connection,budgetTransactionDTO);

                budgetDetailsDTO = budgetAllocationDao.readBudgetDetails(connection,fiscalYear,minCode,accountNum,accountSubNum,departmentId,programRefNumber,
                        true);

                if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
                {
                    if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.TRANSFER_FREE_BAL_TO_BUDGET))
                    {
                        if (coaMoiDTO != null && coaDepartmentDTO != null)
                        {
                            budgetDetailsFreeBalance = budgetDetailsDTO.getAC3_AMOUNT_APPROVED().add(budgetDetailsDTO.getAC3_PV_CREDIT_TOTAL())
                                    .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_COMMITMENT())
                                    .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_OBLIGATION()).subtract(budgetDetailsDTO.getAC3_PV_DEBIT_TOTAL());

                            budgetDetailsFreeBalance = budgetDetailsFreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                            budgetDetailsDTO.setAC3_AMOUNT_APPROVED(budgetDetailsDTO.getAC3_AMOUNT_APPROVED().add(
                                    budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            budgetDetailsDTO.setAC3_FREE_BALANCE(budgetDetailsFreeBalance);

                            // Update Budget Details
                            count = budgetAllocationDao.updateBudgetDetails(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);

                            if (count > 0)
                            {
                                departmentFreeBalance = coaDepartmentDTO.getAC2_APPROVED().add(coaDepartmentDTO.getAC2_EXTRA_APPROVED())
                                        .add(coaDepartmentDTO.getAC2_TRANSFERED_TO()).add(coaDepartmentDTO.getAC2_PV_CREDIT_TOTAL())
                                        .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_COMMITMENT())
                                        .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaDepartmentDTO.getAC2_PV_DEBIT_TOTAL())
                                        .subtract(coaDepartmentDTO.getAC2_TRANSFERED_FROM());

                                departmentFreeBalance = departmentFreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                                coaDepartmentDTO.setAC2_TRANSFERED_TO(coaDepartmentDTO.getAC2_TRANSFERED_TO().add(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                if (!programRefNumber.equals("0"))
                                {
                                    coaDepartmentDTO.setAC2_PROGRAM_APPROVED(coaDepartmentDTO.getAC2_PROGRAM_APPROVED().add(
                                            budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                }
                                else
                                {
                                    coaDepartmentDTO.setAC2_NON_PROGRAM_APPROVED(coaDepartmentDTO.getAC2_NON_PROGRAM_APPROVED().add(
                                            budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                                }
                                coaDepartmentDTO.setAC2_FREE_BALANCE(departmentFreeBalance);

                                budgetAllocationDao.updateDepartmentDetails(connection,budgetTransactionDTO,budgetDetailsDTO,coaDepartmentDTO,transactionType);

                            }

                            coaMoifreeBalance = coaMoiDTO.getAC0_APPROVED().add(coaMoiDTO.getAC0_EXTRA_APPROVED()).add(coaMoiDTO.getAC0_TRANSFERED_TO())
                                    .add(coaMoiDTO.getAC0_PV_CREDIT_TOTAL()).subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_COMMITMENT())
                                    .subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaMoiDTO.getAC0_PV_DEBIT_TOTAL())
                                    .subtract(coaMoiDTO.getAC0_TRANSFERED_FROM());

                            coaMoifreeBalance = coaMoifreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                            coaMoiDTO.setAC0_TRANSFERED_TO(coaMoiDTO.getAC0_TRANSFERED_TO().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            if (!programRefNumber.equals("0"))
                            {
                                coaMoiDTO.setAC0_PROGRAM_APPROVED(coaMoiDTO.getAC0_PROGRAM_APPROVED().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            }
                            else
                            {
                                coaMoiDTO.setAC0_NON_PROGRAM_APPROVED(coaMoiDTO.getAC0_NON_PROGRAM_APPROVED().add(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            }
                            coaMoiDTO.setAC0_FREE_BALANCE(coaMoifreeBalance);

                            budgetAllocationDao.updateCoaMoi(connection,budgetTransactionDTO,coaMoiDTO,transactionType); // Update COA_MOI

                            if (programDistributionDTO != null)
                            {
                                budgetTransactionDTO.setAC8_ACCOUNT_NUMBER(accountNum);
                                budgetTransactionDTO.setAC8_ACCOUNT_SUB_NUMBER(accountSubNum);
                                programDistributionDao.updateProgramDistribution(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);
                                programYearsDao.updateProgramYears(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);
                                programDao.updateProgram(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);
                            }
                            budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO);
                        }
                    }
                }
            }

            if (messages.isEmpty())
            {
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null);
            }
            return messages;
        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
    }

    // CREATE TRANSFER FROM NON_DISTRIBUTED FUND OF BUDGET CLAUSE
    /**
     * This process will be called whenever amount is transferred from Non-Distributed fund of the Budget clause. This process will create a record in the
     * TAC8_BUDGET_TRANSACTION table using the input which is passed to this process.
     * */

    public List<MessageDTO> createTransferFromNonDistributedFundOfBudgetClause(Connection connection, BudgetTransactionDTO budgetTransactionDTO)
            throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO,Set reasonCode ) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.TRANSFER_FROM_NON_DISTRIBUTED);
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }

            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public List<MessageDTO> execTransferFromNonDistributeBudgetClause(Connection connection, String transId, String transactionSetId) throws ERPException
    {
        CoaMoiDTO coaMoi = new CoaMoiDTO();
        CoaMoiDTO coaMoiDTO = new CoaMoiDTO();
        BigDecimal coaMoifreeBalance = new BigDecimal(0);
        String fiscalYear = null;
        String minCode = null;
        String accountNum = null;
        String accountSubNum = null;
        String transactionType = null;
        String transactionStatus = null;
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "( called.");
        }

        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();
            BudgetTransactionDTO budgetTransactionDTO = new BudgetTransactionDTO();
            // budgetTransactionCollection =
            // budgetAllocationDao.readBudgetTransaction(connection,BudgetTransactionDTO.class.newInstance(),transactionSetId,false);
            budgetTransactionDTO = budgetAllocationDao.readOneBudgetTransaction(connection,transId,transactionSetId,true);

            transactionType = budgetTransactionDTO.getAC8_TRANSACTION_TYPE();
            transactionStatus = budgetTransactionDTO.getAC8_TRANSACTION_STATUS();
            fiscalYear = budgetTransactionDTO.getAC8_FISCAL_YEAR();
            minCode = budgetTransactionDTO.getAC8_ACCOUNT_MINISTRY_NUMBER();
            accountNum = budgetTransactionDTO.getAC8_ACCOUNT_NUMBER();
            accountSubNum = budgetTransactionDTO.getAC8_ACCOUNT_SUB_NUMBER();

            coaMoi.setAC0_FISCAL_YEAR(fiscalYear);
            coaMoi.setAC0_ACCOUNT_MINISTRY_NUMBER(minCode);
            coaMoi.setAC0_ACCOUNT_NUMBER(accountNum);
            coaMoi.setAC0_ACCOUNT_SUB_NUMBER(accountSubNum);

            coaMoiDTO = budgetAllocationDao.readBudgetAllocation(connection,coaMoi,false); // Validate Budget Clause

            if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
            {
                if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.TRANSFER_FROM_NON_DISTRIBUTED))
                {
                    if (coaMoiDTO != null)
                    {

                        coaMoifreeBalance = coaMoiDTO.getAC0_APPROVED().add(coaMoiDTO.getAC0_EXTRA_APPROVED()).add(coaMoiDTO.getAC0_TRANSFERED_TO())
                                .add(coaMoiDTO.getAC0_PV_CREDIT_TOTAL()).subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_COMMITMENT())
                                .subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaMoiDTO.getAC0_PV_DEBIT_TOTAL())
                                .subtract(coaMoiDTO.getAC0_TRANSFERED_FROM());

                        coaMoifreeBalance = coaMoifreeBalance.subtract(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                        coaMoiDTO.setAC0_TRANSFERED_FROM(coaMoiDTO.getAC0_TRANSFERED_FROM().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                        coaMoiDTO.setAC0_NON_DISTRIBUTED(coaMoiDTO.getAC0_NON_DISTRIBUTED().subtract(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                        coaMoiDTO.setAC0_FREE_BALANCE(coaMoifreeBalance);

                        budgetAllocationDao.updateCoaMoi(connection,budgetTransactionDTO,coaMoiDTO,transactionType); // Update COA_MOI

                        budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO);
                    }
                }
            }

            if (messages.isEmpty())
            {
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null);
            }
            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
    }

    // CREATE TRANSFER TO NON_DISTRIBUTED FUND OF BUDGET CLAUSE
    /**
     * This process will be called whenever amount is transferred from Non-Distributed fund of the Budget clause. This process will create a record in the
     * TAC8_BUDGET_TRANSACTION table using the input which is passed to this process. *
     * */

    public List<MessageDTO> createTransferToNonDistributedFundOfBudgetClause(Connection connection, BudgetTransactionDTO budgetTransactionDTO)
            throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.TRANSFER_TO_NON_DISTRIBUTED);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }

            return messages;
        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public List<MessageDTO> execTransferToNonDistributeBudgetClause(Connection connection, String transId, String transactionSetId) throws ERPException
    {

        log.info("transferToNonDistributeBudgetClause called.");

        CoaMoiDTO coaMoi = new CoaMoiDTO();
        CoaMoiDTO coaMoiDTO = new CoaMoiDTO();

        BigDecimal extraApprovedAmount = new BigDecimal(0);
        BigDecimal coaMoifreeBalance = new BigDecimal(0);
        String fiscalYear = null;
        String minCode = null;
        String accountNum = null;
        String accountSubNum = null;
        String transactionType = null;
        String transactionStatus = null;
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();
        if (log.isInfoEnabled())
        {
            log.info(methodName + "( called.");
        }

        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();
            BudgetTransactionDTO budgetTransactionDTO = new BudgetTransactionDTO();

            // budgetTransactionCollection =
            // budgetAllocationDao.readBudgetTransaction(connection,BudgetTransactionDTO.class.newInstance(),transactionSetId,false);
            budgetTransactionDTO = budgetAllocationDao.readOneBudgetTransaction(connection,transId,transactionSetId,true);

            transactionType = budgetTransactionDTO.getAC8_TRANSACTION_TYPE();
            transactionStatus = budgetTransactionDTO.getAC8_TRANSACTION_STATUS();
            fiscalYear = budgetTransactionDTO.getAC8_FISCAL_YEAR();
            minCode = budgetTransactionDTO.getAC8_ACCOUNT_MINISTRY_NUMBER();
            accountNum = budgetTransactionDTO.getAC8_ACCOUNT_NUMBER();
            accountSubNum = budgetTransactionDTO.getAC8_ACCOUNT_SUB_NUMBER();

            coaMoi.setAC0_FISCAL_YEAR(fiscalYear);
            coaMoi.setAC0_ACCOUNT_MINISTRY_NUMBER(minCode);
            coaMoi.setAC0_ACCOUNT_NUMBER(accountNum);
            coaMoi.setAC0_ACCOUNT_SUB_NUMBER(accountSubNum);

            coaMoiDTO = budgetAllocationDao.readBudgetAllocation(connection,coaMoi,false);

            if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
            {
                if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.TRANSFER_TO_NON_DISTRIBUTED))
                {
                    if (coaMoiDTO != null)
                    {
                        coaMoifreeBalance = coaMoiDTO.getAC0_APPROVED().add(coaMoiDTO.getAC0_EXTRA_APPROVED()).add(coaMoiDTO.getAC0_TRANSFERED_TO())
                                .add(coaMoiDTO.getAC0_PV_CREDIT_TOTAL()).subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_COMMITMENT())
                                .subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaMoiDTO.getAC0_PV_DEBIT_TOTAL())
                                .subtract(coaMoiDTO.getAC0_TRANSFERED_FROM());

                        coaMoifreeBalance = coaMoifreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                        coaMoiDTO.setAC0_TRANSFERED_TO(coaMoiDTO.getAC0_TRANSFERED_TO().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                        coaMoiDTO.setAC0_NON_DISTRIBUTED(coaMoiDTO.getAC0_NON_DISTRIBUTED().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                        coaMoiDTO.setAC0_FREE_BALANCE(coaMoifreeBalance);

                        budgetAllocationDao.updateCoaMoi(connection,budgetTransactionDTO,coaMoiDTO,transactionType); // Update COA_MOI

                        budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO);
                    }
                }
            }

            if (messages.isEmpty())
            {
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null);
            }
            return messages;
        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
    }

    public List<MessageDTO> createTransferFreeBalanceFromDept(Connection connection, BudgetTransactionDTO budgetTransactionDTO) throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.TRANSFER_FREE_BAL_FROM_DEPT);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }

            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public List<MessageDTO> createTransferFreeBalanceToDept(Connection connection, BudgetTransactionDTO budgetTransactionDTO) throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO) called.");
        }
        try
        {
            // VALIDATE BUDGET CLAUSE
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.TRANSFER_FREE_BAL_TO_DEPT);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }

            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    /**
     * This transaction contains 2 execute transactions 'TRANSFER_FREE_BAL_FROM_DEPT' and 'TRANSFER_FREE_BAL_TO_DEPT'
     * 
     * @param connection
     * @param transactionSetId
     * @return
     * @throws ERPException
     */
    public List<MessageDTO> execTransferFreeBalanceDepartments(Connection connection, String transId, String transactionSetId) throws ERPException
    {

        CoaMoiDTO coaMoi = new CoaMoiDTO();
        CoaMoiDTO coaMoiDTO = new CoaMoiDTO();
        COADepartmentDTO coaDepartmentDTO = new COADepartmentDTO();
        ProgramDistributionDTO programDistributionDTO = new ProgramDistributionDTO();
        ProgramDistributionDao programDistributionDao = new ProgramDistributionDao();
        ProgramYearsDao programYearsDao = new ProgramYearsDao();
        ProgramDao programDao = new ProgramDao();
        BigDecimal budgetDetailsFreeBalance = new BigDecimal(0);
        BigDecimal departmentFreeBalance = new BigDecimal(0);
        String fiscalYear = null;
        String minCode = null;
        String accountNum = null;
        String accountSubNum = null;
        String transactionType = null;
        String transactionStatus = null;
        String departmentId = null;
        String programRefNumber = null;
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "( called.");
        }
        int count = 0;

        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            BudgetTransactionDTO budgetTransactionDTO = new BudgetTransactionDTO();
            BudgetDetailsDTO budgetDetailsDTO = new BudgetDetailsDTO();

            // budgetTransactionCollection =
            // budgetAllocationDao.readBudgetTransaction(connection,BudgetTransactionDTO.class.newInstance(),transactionSetId,false);
            budgetTransactionDTO = budgetAllocationDao.readOneBudgetTransaction(connection,transId,transactionSetId,true);

            transactionType = budgetTransactionDTO.getAC8_TRANSACTION_TYPE();
            transactionStatus = budgetTransactionDTO.getAC8_TRANSACTION_STATUS();
            fiscalYear = budgetTransactionDTO.getAC8_FISCAL_YEAR();
            minCode = budgetTransactionDTO.getAC8_ACCOUNT_MINISTRY_NUMBER();
            accountNum = budgetTransactionDTO.getAC8_ACCOUNT_NUMBER();
            accountSubNum = budgetTransactionDTO.getAC8_ACCOUNT_SUB_NUMBER();
            departmentId = budgetTransactionDTO.getAC8_DEPARTMENT();

            if (budgetTransactionDTO.getAC8_PROGRAM_REF_NUMBER() != null)
            {
                programRefNumber = budgetTransactionDTO.getAC8_PROGRAM_REF_NUMBER().trim();
                programDistributionDTO = programDistributionDao.readProgramDistribution(connection,minCode,accountNum,accountSubNum,fiscalYear,
                        programRefNumber,departmentId,false);
            }
            else
            {
                programRefNumber = "0";
            }

            coaMoi.setAC0_FISCAL_YEAR(fiscalYear);
            coaMoi.setAC0_ACCOUNT_MINISTRY_NUMBER(minCode);
            coaMoi.setAC0_ACCOUNT_NUMBER(accountNum);
            coaMoi.setAC0_ACCOUNT_SUB_NUMBER(accountSubNum);

            coaMoiDTO = budgetAllocationDao.readBudgetAllocation(connection,coaMoi,false);

            coaDepartmentDTO = budgetAllocationDao.readDepartmentDetails(connection,budgetTransactionDTO);

            budgetDetailsDTO = budgetAllocationDao.readBudgetDetails(connection,fiscalYear,minCode,accountNum,accountSubNum,departmentId,programRefNumber,true);

            if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
            {
                if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.TRANSFER_FREE_BAL_FROM_DEPT))
                {
                    if (coaMoiDTO != null && coaDepartmentDTO != null && budgetDetailsDTO != null)
                    {
                        budgetDetailsFreeBalance = budgetDetailsDTO.getAC3_AMOUNT_APPROVED().add(budgetDetailsDTO.getAC3_PV_CREDIT_TOTAL())
                                .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_COMMITMENT()).subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_OBLIGATION())
                                .subtract(budgetDetailsDTO.getAC3_PV_DEBIT_TOTAL());

                        budgetDetailsFreeBalance = budgetDetailsFreeBalance.subtract(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                        budgetDetailsDTO.setAC3_AMOUNT_APPROVED(budgetDetailsDTO.getAC3_AMOUNT_APPROVED().subtract(
                                budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                        budgetDetailsDTO.setAC3_FREE_BALANCE(budgetDetailsFreeBalance);

                        // Update Budget Details
                        count = budgetAllocationDao.updateBudgetDetails(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);

                        if (count > 0)
                        {
                            departmentFreeBalance = coaDepartmentDTO.getAC2_APPROVED().add(coaDepartmentDTO.getAC2_EXTRA_APPROVED())
                                    .add(coaDepartmentDTO.getAC2_TRANSFERED_TO()).add(coaDepartmentDTO.getAC2_PV_CREDIT_TOTAL())
                                    .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_COMMITMENT())
                                    .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaDepartmentDTO.getAC2_PV_DEBIT_TOTAL())
                                    .subtract(coaDepartmentDTO.getAC2_TRANSFERED_FROM());

                            departmentFreeBalance = departmentFreeBalance.subtract(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                            coaDepartmentDTO.setAC2_TRANSFERED_FROM(coaDepartmentDTO.getAC2_TRANSFERED_FROM().add(
                                    budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));

                            if (!programRefNumber.equals("0") && programDistributionDTO != null)
                            {
                                coaDepartmentDTO.setAC2_PROGRAM_APPROVED(coaDepartmentDTO.getAC2_PROGRAM_APPROVED().subtract(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            }
                            else
                            {
                                coaDepartmentDTO.setAC2_NON_PROGRAM_APPROVED(coaDepartmentDTO.getAC2_NON_PROGRAM_APPROVED().subtract(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            }
                            coaDepartmentDTO.setAC2_FREE_BALANCE(departmentFreeBalance);

                            budgetAllocationDao.updateDepartmentDetails(connection,budgetTransactionDTO,budgetDetailsDTO,coaDepartmentDTO,transactionType);

                        }

                        if (!programRefNumber.equals("0") && programDistributionDTO != null)
                        {
                            budgetTransactionDTO.setAC8_ACCOUNT_NUMBER(accountNum);
                            budgetTransactionDTO.setAC8_ACCOUNT_SUB_NUMBER(accountSubNum);
                            // Update Program Distribution
                            programDistributionDao.updateProgramDistribution(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);

                            programYearsDao.updateProgramYears(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType); // Update PgmYrs
                            programDao.updateProgram(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType); // Update PROGRAM
                        }

                        budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO);
                    }
                }
            }
            if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
            {
                if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.TRANSFER_FREE_BAL_TO_DEPT))
                {
                    if (coaMoiDTO != null && coaDepartmentDTO != null && budgetDetailsDTO != null)
                    {
                        budgetDetailsFreeBalance = budgetDetailsDTO.getAC3_AMOUNT_APPROVED().add(budgetDetailsDTO.getAC3_PV_CREDIT_TOTAL())
                                .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_COMMITMENT()).subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_OBLIGATION())
                                .subtract(budgetDetailsDTO.getAC3_PV_DEBIT_TOTAL());

                        budgetDetailsFreeBalance = budgetDetailsFreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                        budgetDetailsDTO
                                .setAC3_AMOUNT_APPROVED(budgetDetailsDTO.getAC3_AMOUNT_APPROVED().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                        budgetDetailsDTO.setAC3_FREE_BALANCE(budgetDetailsFreeBalance);

                        // Update Budget Details
                        count = budgetAllocationDao.updateBudgetDetails(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);

                        if (count > 0)
                        {
                            departmentFreeBalance = coaDepartmentDTO.getAC2_APPROVED().add(coaDepartmentDTO.getAC2_EXTRA_APPROVED())
                                    .add(coaDepartmentDTO.getAC2_TRANSFERED_TO()).add(coaDepartmentDTO.getAC2_PV_CREDIT_TOTAL())
                                    .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_COMMITMENT())
                                    .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaDepartmentDTO.getAC2_PV_DEBIT_TOTAL())
                                    .subtract(coaDepartmentDTO.getAC2_TRANSFERED_FROM());

                            departmentFreeBalance = departmentFreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                            coaDepartmentDTO
                                    .setAC2_TRANSFERED_TO(coaDepartmentDTO.getAC2_TRANSFERED_TO().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            if (!programRefNumber.equals("0") && programDistributionDTO != null)
                            {
                                coaDepartmentDTO.setAC2_PROGRAM_APPROVED(coaDepartmentDTO.getAC2_PROGRAM_APPROVED().add(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            }
                            else
                            {
                                coaDepartmentDTO.setAC2_NON_PROGRAM_APPROVED(coaDepartmentDTO.getAC2_NON_PROGRAM_APPROVED().add(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            }
                            coaDepartmentDTO.setAC2_FREE_BALANCE(departmentFreeBalance);

                            budgetAllocationDao.updateDepartmentDetails(connection,budgetTransactionDTO,budgetDetailsDTO,coaDepartmentDTO,transactionType);

                        }

                        if (!programRefNumber.equals("0") && programDistributionDTO != null)
                        {
                            budgetTransactionDTO.setAC8_ACCOUNT_NUMBER(accountNum);
                            budgetTransactionDTO.setAC8_ACCOUNT_SUB_NUMBER(accountSubNum);
                            // Update Program Distribution
                            programDistributionDao.updateProgramDistribution(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);

                            programYearsDao.updateProgramYears(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType); // Update PgmYrs
                            programDao.updateProgram(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType); // Update PROGRAM
                        }

                        budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO);
                    }
                }
            }

            if (messages.isEmpty())
            {
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null);
            }
            return messages;
        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
    }

    /**
     * @param connection
     * @param budgetTransactionDTO
     * @return
     * @throws ERPException
     * 
     * 
     */
    public List<MessageDTO> createDecreaseNonDistributedFundOfBudgetClause(Connection connection, BudgetTransactionDTO budgetTransactionDTO)
            throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO,Set reasonCode ) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.DECREASE_NON_DISTRIBUTED);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }

            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public List<MessageDTO> execDecreaseNonDistributeBudgetClause(Connection connection, String transId, String transactionSetId) throws ERPException
    {
        CoaMoiDTO coaMoi = new CoaMoiDTO();
        CoaMoiDTO coaMoiDTO = new CoaMoiDTO();
        BigDecimal coaMoifreeBalance = new BigDecimal(0);
        String fiscalYear = null;
        String minCode = null;
        String accountNum = null;
        String accountSubNum = null;
        String transactionType = null;
        String transactionStatus = null;
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "( called.");
        }

        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();
            BudgetTransactionDTO budgetTransactionDTO = new BudgetTransactionDTO();

            // budgetTransactionCollection =
            // budgetAllocationDao.readBudgetTransaction(connection,BudgetTransactionDTO.class.newInstance(),transactionSetId,false);
            budgetTransactionDTO = budgetAllocationDao.readOneBudgetTransaction(connection,transId,transactionSetId,true);

            transactionType = budgetTransactionDTO.getAC8_TRANSACTION_TYPE();
            transactionStatus = budgetTransactionDTO.getAC8_TRANSACTION_STATUS();
            fiscalYear = budgetTransactionDTO.getAC8_FISCAL_YEAR();
            minCode = budgetTransactionDTO.getAC8_ACCOUNT_MINISTRY_NUMBER();
            accountNum = budgetTransactionDTO.getAC8_ACCOUNT_NUMBER();
            accountSubNum = budgetTransactionDTO.getAC8_ACCOUNT_SUB_NUMBER();

            coaMoi.setAC0_FISCAL_YEAR(fiscalYear);
            coaMoi.setAC0_ACCOUNT_MINISTRY_NUMBER(minCode);
            coaMoi.setAC0_ACCOUNT_NUMBER(accountNum);
            coaMoi.setAC0_ACCOUNT_SUB_NUMBER(accountSubNum);

            coaMoiDTO = budgetAllocationDao.readBudgetAllocation(connection,coaMoi,false); // Validate Budget Clause

            if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
            {
                if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.DECREASE_NON_DISTRIBUTED))
                {
                    if (coaMoiDTO != null)
                    {

                        coaMoifreeBalance = coaMoiDTO.getAC0_APPROVED().add(coaMoiDTO.getAC0_EXTRA_APPROVED()).add(coaMoiDTO.getAC0_TRANSFERED_TO())
                                .add(coaMoiDTO.getAC0_PV_CREDIT_TOTAL()).subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_COMMITMENT())
                                .subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaMoiDTO.getAC0_PV_DEBIT_TOTAL())
                                .subtract(coaMoiDTO.getAC0_TRANSFERED_FROM());

                        coaMoifreeBalance = coaMoifreeBalance.subtract(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                        coaMoiDTO.setAC0_NON_DISTRIBUTED(coaMoiDTO.getAC0_NON_DISTRIBUTED().subtract(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                        coaMoiDTO.setAC0_FREE_BALANCE(coaMoifreeBalance);

                        budgetAllocationDao.updateCoaMoi(connection,budgetTransactionDTO,coaMoiDTO,transactionType); // Update COA_MOI

                        budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO);
                    }
                }
            }

            if (messages.isEmpty())
            {
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null);
            }
            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
    }

    public List<MessageDTO> createIncreaseNonDistributedFundOfBudgetClause(Connection connection, BudgetTransactionDTO budgetTransactionDTO)
            throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.INCREASE_NON_DISTRIBUTED);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }

            return messages;
        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public List<MessageDTO> execIncreaseNonDistributeBudgetClause(Connection connection, String transId, String transactionSetId) throws ERPException
    {

        CoaMoiDTO coaMoi = new CoaMoiDTO();
        CoaMoiDTO coaMoiDTO = new CoaMoiDTO();

        BigDecimal coaMoifreeBalance = new BigDecimal(0);
        String fiscalYear = null;
        String minCode = null;
        String accountNum = null;
        String accountSubNum = null;
        String transactionType = null;
        String transactionStatus = null;
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();
        if (log.isInfoEnabled())
        {
            log.info(methodName + "( called.");
        }

        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();
            BudgetTransactionDTO budgetTransactionDTO = new BudgetTransactionDTO();

            // budgetTransactionCollection =
            // budgetAllocationDao.readBudgetTransaction(connection,BudgetTransactionDTO.class.newInstance(),transactionSetId,false);
            budgetTransactionDTO = budgetAllocationDao.readOneBudgetTransaction(connection,transId,transactionSetId,true);

            transactionType = budgetTransactionDTO.getAC8_TRANSACTION_TYPE();
            transactionStatus = budgetTransactionDTO.getAC8_TRANSACTION_STATUS();
            fiscalYear = budgetTransactionDTO.getAC8_FISCAL_YEAR();
            minCode = budgetTransactionDTO.getAC8_ACCOUNT_MINISTRY_NUMBER();
            accountNum = budgetTransactionDTO.getAC8_ACCOUNT_NUMBER();
            accountSubNum = budgetTransactionDTO.getAC8_ACCOUNT_SUB_NUMBER();

            coaMoi.setAC0_FISCAL_YEAR(fiscalYear);
            coaMoi.setAC0_ACCOUNT_MINISTRY_NUMBER(minCode);
            coaMoi.setAC0_ACCOUNT_NUMBER(accountNum);
            coaMoi.setAC0_ACCOUNT_SUB_NUMBER(accountSubNum);

            coaMoiDTO = budgetAllocationDao.readBudgetAllocation(connection,coaMoi,false);

            if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
            {
                if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.INCREASE_NON_DISTRIBUTED))
                {
                    if (coaMoiDTO != null)
                    {
                        coaMoifreeBalance = coaMoiDTO.getAC0_APPROVED().add(coaMoiDTO.getAC0_EXTRA_APPROVED()).add(coaMoiDTO.getAC0_TRANSFERED_TO())
                                .add(coaMoiDTO.getAC0_PV_CREDIT_TOTAL()).subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_COMMITMENT())
                                .subtract(coaMoiDTO.getAC0_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaMoiDTO.getAC0_PV_DEBIT_TOTAL())
                                .subtract(coaMoiDTO.getAC0_TRANSFERED_FROM());

                        coaMoifreeBalance = coaMoifreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                        coaMoiDTO.setAC0_NON_DISTRIBUTED(coaMoiDTO.getAC0_NON_DISTRIBUTED().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                        coaMoiDTO.setAC0_FREE_BALANCE(coaMoifreeBalance);

                        budgetAllocationDao.updateCoaMoi(connection,budgetTransactionDTO,coaMoiDTO,transactionType); // Update COA_MOI

                        budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO);
                    }
                }
            }

            if (messages.isEmpty())
            {
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null);
            }
            return messages;
        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
    }

    /**
     * @param connection
     * @param budgetTransactionDTO
     * @return
     * @throws ERPException
     */
    public List<MessageDTO> createDecreaseFreeBalanceFromDept(Connection connection, BudgetTransactionDTO budgetTransactionDTO) throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO) called.");
        }
        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.DECREASE_FREE_BAL_FROM_DEPT);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }

            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    public List<MessageDTO> createIncreaseFreeBalanceToDept(Connection connection, BudgetTransactionDTO budgetTransactionDTO) throws ERPException
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "(Connection connection, BudgetTransactionDTO budgetTransactionDTO) called.");
        }
        try
        {
            // VALIDATE BUDGET CLAUSE
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            if (budgetTransactionDTO != null)
            {
                budgetTransactionDTO.setAC8_TRANSACTION_STATUS("PENDING");
                budgetTransactionDTO.setAC8_TRANSACTION_TYPE(ERPTransactionsTypes.BUDGET.INCREASE_FREE_BAL_TO_DEPT);

                String transactionId = UUID.randomUUID().toString().replaceAll("-","");
                budgetTransactionDTO.setAC8_TRANSACTION_ID(transactionId);

                budgetAllocationDao.createBudgetTransaction(connection,budgetTransactionDTO);
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null,true);
            }

            return messages;

        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));

        }
    }

    /**
     * @param connection
     * @param transactionSetId
     * @return
     * @throws ERPException
     */
    public List<MessageDTO> execIncreaseDecreaseFreeBalanceOfDepartment(Connection connection, String transId, String transactionSetId) throws ERPException
    {

        CoaMoiDTO coaMoi = new CoaMoiDTO();
        CoaMoiDTO coaMoiDTO = new CoaMoiDTO();
        COADepartmentDTO coaDepartmentDTO = new COADepartmentDTO();
        ProgramDistributionDTO programDistributionDTO = new ProgramDistributionDTO();
        ProgramDistributionDao programDistributionDao = new ProgramDistributionDao();
        ProgramYearsDao programYearsDao = new ProgramYearsDao();
        ProgramDao programDao = new ProgramDao();
        BigDecimal budgetDetailsFreeBalance = new BigDecimal(0);
        BigDecimal departmentFreeBalance = new BigDecimal(0);
        String fiscalYear = null;
        String minCode = null;
        String accountNum = null;
        String accountSubNum = null;
        String transactionType = null;
        String transactionStatus = null;
        String departmentId = null;
        String programRefNumber = null;
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        List<MessageDTO> messages = new ArrayList<MessageDTO>();

        if (log.isInfoEnabled())
        {
            log.info(methodName + "( called.");
        }
        int count = 0;

        try
        {
            BudgetAllocationDao budgetAllocationDao = new BudgetAllocationDao();

            BudgetTransactionDTO budgetTransactionDTO = new BudgetTransactionDTO();
            BudgetDetailsDTO budgetDetailsDTO = new BudgetDetailsDTO();

            // budgetTransactionCollection =
            // budgetAllocationDao.readBudgetTransaction(connection,BudgetTransactionDTO.class.newInstance(),transactionSetId,false);
            budgetTransactionDTO = budgetAllocationDao.readOneBudgetTransaction(connection,transId,transactionSetId,true);

            transactionType = budgetTransactionDTO.getAC8_TRANSACTION_TYPE();
            transactionStatus = budgetTransactionDTO.getAC8_TRANSACTION_STATUS();
            fiscalYear = budgetTransactionDTO.getAC8_FISCAL_YEAR();
            minCode = budgetTransactionDTO.getAC8_ACCOUNT_MINISTRY_NUMBER();
            accountNum = budgetTransactionDTO.getAC8_ACCOUNT_NUMBER();
            accountSubNum = budgetTransactionDTO.getAC8_ACCOUNT_SUB_NUMBER();
            departmentId = budgetTransactionDTO.getAC8_DEPARTMENT();

            if (budgetTransactionDTO.getAC8_PROGRAM_REF_NUMBER() != null)
            {
                programRefNumber = budgetTransactionDTO.getAC8_PROGRAM_REF_NUMBER().trim();
                programDistributionDTO = programDistributionDao.readProgramDistribution(connection,minCode,accountNum,accountSubNum,fiscalYear,
                        programRefNumber,departmentId,false);
            }
            else
            {
                programRefNumber = "0";
            }

            coaMoi.setAC0_FISCAL_YEAR(fiscalYear);
            coaMoi.setAC0_ACCOUNT_MINISTRY_NUMBER(minCode);
            coaMoi.setAC0_ACCOUNT_NUMBER(accountNum);
            coaMoi.setAC0_ACCOUNT_SUB_NUMBER(accountSubNum);

            coaMoiDTO = budgetAllocationDao.readBudgetAllocation(connection,coaMoi,false);

            coaDepartmentDTO = budgetAllocationDao.readDepartmentDetails(connection,budgetTransactionDTO);

            budgetDetailsDTO = budgetAllocationDao.readBudgetDetails(connection,fiscalYear,minCode,accountNum,accountSubNum,departmentId,programRefNumber,true);

            if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
            {
                if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.DECREASE_FREE_BAL_FROM_DEPT))
                {
                    if (coaMoiDTO != null && coaDepartmentDTO != null && budgetDetailsDTO != null)
                    {
                        budgetDetailsFreeBalance = budgetDetailsDTO.getAC3_AMOUNT_APPROVED().add(budgetDetailsDTO.getAC3_PV_CREDIT_TOTAL())
                                .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_COMMITMENT()).subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_OBLIGATION())
                                .subtract(budgetDetailsDTO.getAC3_PV_DEBIT_TOTAL());

                        budgetDetailsFreeBalance = budgetDetailsFreeBalance.subtract(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                        budgetDetailsDTO.setAC3_AMOUNT_APPROVED(budgetDetailsDTO.getAC3_AMOUNT_APPROVED().subtract(
                                budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                        budgetDetailsDTO.setAC3_FREE_BALANCE(budgetDetailsFreeBalance);

                        // Update Budget Details
                        count = budgetAllocationDao.updateBudgetDetails(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);

                        if (count > 0)
                        {
                            departmentFreeBalance = coaDepartmentDTO.getAC2_APPROVED().add(coaDepartmentDTO.getAC2_EXTRA_APPROVED())
                                    .add(coaDepartmentDTO.getAC2_TRANSFERED_TO()).add(coaDepartmentDTO.getAC2_PV_CREDIT_TOTAL())
                                    .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_COMMITMENT())
                                    .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaDepartmentDTO.getAC2_PV_DEBIT_TOTAL())
                                    .subtract(coaDepartmentDTO.getAC2_TRANSFERED_FROM());

                            departmentFreeBalance = departmentFreeBalance.subtract(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                            coaDepartmentDTO.setAC2_EXTRA_APPROVED(coaDepartmentDTO.getAC2_EXTRA_APPROVED().subtract(
                                    budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));

                            if (!programRefNumber.equals("0") && programDistributionDTO != null)
                            {
                                coaDepartmentDTO.setAC2_PROGRAM_APPROVED(coaDepartmentDTO.getAC2_PROGRAM_APPROVED().subtract(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            }
                            else
                            {
                                coaDepartmentDTO.setAC2_NON_PROGRAM_APPROVED(coaDepartmentDTO.getAC2_NON_PROGRAM_APPROVED().subtract(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            }
                            coaDepartmentDTO.setAC2_FREE_BALANCE(departmentFreeBalance);

                            budgetAllocationDao.updateDepartmentDetails(connection,budgetTransactionDTO,budgetDetailsDTO,coaDepartmentDTO,transactionType);

                        }

                        if (!programRefNumber.equals("0") && programDistributionDTO != null)
                        {
                            budgetTransactionDTO.setAC8_ACCOUNT_NUMBER(accountNum);
                            budgetTransactionDTO.setAC8_ACCOUNT_SUB_NUMBER(accountSubNum);
                            // Update Program Distribution
                            programDistributionDao.updateProgramDistribution(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);

                            programYearsDao.updateProgramYears(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType); // Update PgmYrs
                            programDao.updateProgram(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType); // Update PROGRAM
                        }

                        budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO);
                    }
                }
            }
            if (!transactionStatus.trim().equals(ERPTransactionsTypes.STATUS.POSTED))
            {
                if (transactionType.trim().equals(ERPTransactionsTypes.BUDGET.INCREASE_FREE_BAL_TO_DEPT))
                {
                    if (coaMoiDTO != null && coaDepartmentDTO != null && budgetDetailsDTO != null)
                    {
                        budgetDetailsFreeBalance = budgetDetailsDTO.getAC3_AMOUNT_APPROVED().add(budgetDetailsDTO.getAC3_PV_CREDIT_TOTAL())
                                .subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_COMMITMENT()).subtract(budgetDetailsDTO.getAC3_TOTAL_FINANCIAL_OBLIGATION())
                                .subtract(budgetDetailsDTO.getAC3_PV_DEBIT_TOTAL());

                        budgetDetailsFreeBalance = budgetDetailsFreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                        budgetDetailsDTO
                                .setAC3_AMOUNT_APPROVED(budgetDetailsDTO.getAC3_AMOUNT_APPROVED().add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                        budgetDetailsDTO.setAC3_FREE_BALANCE(budgetDetailsFreeBalance);

                        // Update Budget Details
                        count = budgetAllocationDao.updateBudgetDetails(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);

                        if (count > 0)
                        {
                            departmentFreeBalance = coaDepartmentDTO.getAC2_APPROVED().add(coaDepartmentDTO.getAC2_EXTRA_APPROVED())
                                    .add(coaDepartmentDTO.getAC2_TRANSFERED_TO()).add(coaDepartmentDTO.getAC2_PV_CREDIT_TOTAL())
                                    .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_COMMITMENT())
                                    .subtract(coaDepartmentDTO.getAC2_TOTAL_FINANCIAL_OBLIGATION()).subtract(coaDepartmentDTO.getAC2_PV_DEBIT_TOTAL())
                                    .subtract(coaDepartmentDTO.getAC2_TRANSFERED_FROM());

                            departmentFreeBalance = departmentFreeBalance.add(budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT());

                            coaDepartmentDTO.setAC2_EXTRA_APPROVED(coaDepartmentDTO.getAC2_EXTRA_APPROVED().add(
                                    budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            if (!programRefNumber.equals("0") && programDistributionDTO != null)
                            {
                                coaDepartmentDTO.setAC2_PROGRAM_APPROVED(coaDepartmentDTO.getAC2_PROGRAM_APPROVED().add(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            }
                            else
                            {
                                coaDepartmentDTO.setAC2_NON_PROGRAM_APPROVED(coaDepartmentDTO.getAC2_NON_PROGRAM_APPROVED().add(
                                        budgetTransactionDTO.getAC8_TRANSACTION_AMOUNT()));
                            }
                            coaDepartmentDTO.setAC2_FREE_BALANCE(departmentFreeBalance);

                            budgetAllocationDao.updateDepartmentDetails(connection,budgetTransactionDTO,budgetDetailsDTO,coaDepartmentDTO,transactionType);

                        }

                        if (!programRefNumber.equals("0") && programDistributionDTO != null)
                        {
                            budgetTransactionDTO.setAC8_ACCOUNT_NUMBER(accountNum);
                            budgetTransactionDTO.setAC8_ACCOUNT_SUB_NUMBER(accountSubNum);
                            // Update Program Distribution
                            programDistributionDao.updateProgramDistribution(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType);

                            programYearsDao.updateProgramYears(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType); // Update PgmYrs
                            programDao.updateProgram(connection,budgetTransactionDTO,budgetDetailsDTO,transactionType); // Update PROGRAM
                        }

                        budgetAllocationDao.updateBudgetTransaction(connection,budgetTransactionDTO);
                    }
                }
            }

            if (messages.isEmpty())
            {
                ERPCoreUtility.addResultCode(ERPTransactionsTypes.MESSAGECODE.SUCCESS,messages,null);
            }
            return messages;
        }
        catch (ERPException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
    }

}
